Troubleshooting
Solutions for common issues, environment variables, performance tips, and security notes.
Quick Diagnosis
| Symptom | Likely Cause | Fix |
|---|---|---|
| Everything marked as "new" | Missing baseline | Mount /main, set CODEWARD_MODE=diff |
| No PR comment posted | Missing env vars | Set CODEWARD_GITHUB_TOKEN, CODEWARD_GITHUB_PR_NUMBER, CODEWARD_GITHUB_OWNER, CODEWARD_GITHUB_REPOSITORY |
| Empty PR report | Wrong change filter | Include new or changed in changes |
| Mixed format combine error | JSON + markdown in combined group | Use same format for all combined outputs |
| Template error with JSON | template set for JSON output | Remove template field |
| Invalid field error | Field not available for policy type | Check allowed fields in Policies |
| Rules ignored | Wrong rules format | Use array: "rules": [{ "field": "...", "type": "...", "value": "..." }] |
| Relationship filter ignored | Dependency tree disabled | Set global.dependency_tree: true |
| Scan doesn't find packages | Dependencies not installed | Run npm ci, pip install, etc. before scanning |
| Validation rule ignored | Nested object instead of array | Use "rules": [{ ... }] array format |
| Permission denied on results | Container can't write | Ensure host directory is writable |
| Rule not working as expected | Misunderstood rule logic | See Understanding Rule Logic below |
Understanding Rule Logic
Common confusion: Rules define what to search for, not requirements to enforce.
The Search Paradigm
All operators report when the condition is true (matches):
| What You Want | Correct Rule | ❌ Common Mistake |
|---|---|---|
| Find CRITICAL vulns | { "type": "eq", "value": "CRITICAL" } | Using ne thinking it blocks non-critical |
| Find large PRs (>30 files) | { "type": "gt", "value": "30" } | Using le thinking it enforces limit |
| Find missing test script | { "type": "not_exists", "key": "scripts.test" } | Using exists thinking it requires test |
| Find WIP PRs | { "type": "contains", "value": "WIP" } | Using not_contains thinking it blocks WIP |
| Find files without USER | { "type": "not_contains", "value": "USER" } | Using contains thinking it requires USER |
How It Works
- Rule evaluates → Checks if condition matches
- Match found (
Passed = true) → Creates a finding - Finding triggers action →
info,warn, orblock
Example:
{
"rules": [
{ "field": "Severity", "type": "eq", "value": "CRITICAL" }
],
"actions": { "new": "block" }
}
This searches for vulnerabilities where severity equals CRITICAL. When found, it blocks the PR.
Key Insight
Think:
- ✅ "Find what I want to block/warn about"
- ❌ "Define requirements that must be met"
See Policies > Understanding Rule Logic for detailed explanation.
Environment Variables
Complete reference for all environment variables:
Required for Scanning
| Variable | Required | Description |
|---|---|---|
CI | Recommended | Set to true to enable CI behaviors |
CODEWARD_MODE | No | diff for PR/branch comparison, main (default) for single-branch scan |
GitHub Integration
| Variable | Required For | Description |
|---|---|---|
CODEWARD_GITHUB_TOKEN | git:pr, git:issue | GitHub API token |
CODEWARD_GITHUB_OWNER | git:pr, git:issue | Repository owner/organization |
CODEWARD_GITHUB_REPOSITORY | git:pr, git:issue | Repository name |
CODEWARD_GITHUB_PR_NUMBER | git:pr | Pull request number |
Configuration
| Variable | Required | Description |
|---|---|---|
CODEWARD_CONFIG_PATH | No | Override config file path |
CODEWARD_PRIVATE_CONFIG_PATH | No | Path to private config overrides |
Docker Volumes
| Mount | Purpose |
|---|---|
/main | Base branch (main) checkout — required |
/branch | Feature branch checkout — required for PR mode |
/results | Output files (reports, JSON) |
/.cache | Trivy database and scan cache |
Common Issues
Everything Shows as "New"
The scanner can't find the baseline to compare against.
Fix:
- Mount the main branch at
/main - Mount the feature branch at
/branch - Set
CODEWARD_MODE=diff
docker run --rm \
-v /path/to/main:/main:rw \
-v /path/to/branch:/branch:rw \
-e CODEWARD_MODE=diff \
ghcr.io/codeward-io/scan:latest
No PR Comment Appears
The scanner can't post to GitHub.
Check:
CODEWARD_GITHUB_TOKENis set and haspull-requests: writescopeCODEWARD_GITHUB_PR_NUMBERis set to the PR numberCODEWARD_GITHUB_OWNERandCODEWARD_GITHUB_REPOSITORYare correctCODEWARD_MODE=diff
Empty Output
No findings matched your policy after filtering.
Check:
changesarray includesnew(not justexisting)- Rules aren't too restrictive
- The diff actually introduces findings (try with fewer rules)
Validation Errors
Common config validation issues:
| Error | Fix |
|---|---|
invalid format | Use markdown, html, or json |
invalid destination | Start with git:, log:, file:, or url: |
template must be empty | Remove template for JSON outputs |
invalid field | Use only allowed fields for the policy type |
missing required field | Add name, actions, rules to policy |
Performance Tips
Caching
Mount a persistent cache directory for faster subsequent scans:
-v /persistent/cache:/.cache:rw
The cache stores:
- Trivy vulnerability database
- Scan metadata for faster reprocessing
Dependency Installation
For accurate transitive dependency detection, install dependencies before scanning:
# In your CI before running Codeward
npm ci
# or
pip install -r requirements.txt
# or
go mod download
Reducing Scan Time
- Start with focused policies: Scan only CRITICAL first, expand later
- Disable dependency tree: Only enable if using
Relationship,Parents,Childrenfilters - Limit outputs: Reduce number of output configurations
Security Notes
Data Handling
- All scanning runs inside the container — no code leaves the runner
- Outputs go only to configured destinations
- No external network calls except:
- Trivy database updates
- Your configured
url:destinations
Token Security
- Use repository-scoped tokens, not personal access tokens
- Grant minimal required permissions:
contents: read— checkoutpackages: read— pull scanner imagepull-requests: write— post comments (if usinggit:pr)issues: write— create issues (if usinggit:issue)
Cache Contents
- Trivy database (vulnerability data)
- Scan metadata
- No credentials are cached
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success — no blocking findings |
| 1 | Failure — at least one block action triggered, or fatal error |