Skip to main content

Troubleshooting

Solutions for common issues, environment variables, performance tips, and security notes.

Quick Diagnosis

SymptomLikely CauseFix
Everything marked as "new"Missing baselineMount /main, set CODEWARD_MODE=diff
No PR comment postedMissing env varsSet CODEWARD_GITHUB_TOKEN, CODEWARD_GITHUB_PR_NUMBER, CODEWARD_GITHUB_OWNER, CODEWARD_GITHUB_REPOSITORY
Empty PR reportWrong change filterInclude new or changed in changes
Mixed format combine errorJSON + markdown in combined groupUse same format for all combined outputs
Template error with JSONtemplate set for JSON outputRemove template field
Invalid field errorField not available for policy typeCheck allowed fields in Policies
Rules ignoredWrong rules formatUse array: "rules": [{ "field": "...", "type": "...", "value": "..." }]
Relationship filter ignoredDependency tree disabledSet global.dependency_tree: true
Scan doesn't find packagesDependencies not installedRun npm ci, pip install, etc. before scanning
Validation rule ignoredNested object instead of arrayUse "rules": [{ ... }] array format
Permission denied on resultsContainer can't writeEnsure host directory is writable
Rule not working as expectedMisunderstood rule logicSee 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 WantCorrect 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

  1. Rule evaluates → Checks if condition matches
  2. Match found (Passed = true) → Creates a finding
  3. Finding triggers actioninfo, warn, or block

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

VariableRequiredDescription
CIRecommendedSet to true to enable CI behaviors
CODEWARD_MODENodiff for PR/branch comparison, main (default) for single-branch scan

GitHub Integration

VariableRequired ForDescription
CODEWARD_GITHUB_TOKENgit:pr, git:issueGitHub API token
CODEWARD_GITHUB_OWNERgit:pr, git:issueRepository owner/organization
CODEWARD_GITHUB_REPOSITORYgit:pr, git:issueRepository name
CODEWARD_GITHUB_PR_NUMBERgit:prPull request number

Configuration

VariableRequiredDescription
CODEWARD_CONFIG_PATHNoOverride config file path
CODEWARD_PRIVATE_CONFIG_PATHNoPath to private config overrides

Docker Volumes

MountPurpose
/mainBase branch (main) checkout — required
/branchFeature branch checkout — required for PR mode
/resultsOutput files (reports, JSON)
/.cacheTrivy database and scan cache

Common Issues

Everything Shows as "New"

The scanner can't find the baseline to compare against.

Fix:

  1. Mount the main branch at /main
  2. Mount the feature branch at /branch
  3. 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:

  1. CODEWARD_GITHUB_TOKEN is set and has pull-requests: write scope
  2. CODEWARD_GITHUB_PR_NUMBER is set to the PR number
  3. CODEWARD_GITHUB_OWNER and CODEWARD_GITHUB_REPOSITORY are correct
  4. CODEWARD_MODE=diff

Empty Output

No findings matched your policy after filtering.

Check:

  1. changes array includes new (not just existing)
  2. Rules aren't too restrictive
  3. The diff actually introduces findings (try with fewer rules)

Validation Errors

Common config validation issues:

ErrorFix
invalid formatUse markdown, html, or json
invalid destinationStart with git:, log:, file:, or url:
template must be emptyRemove template for JSON outputs
invalid fieldUse only allowed fields for the policy type
missing required fieldAdd 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

  1. Start with focused policies: Scan only CRITICAL first, expand later
  2. Disable dependency tree: Only enable if using Relationship, Parents, Children filters
  3. 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 — checkout
    • packages: read — pull scanner image
    • pull-requests: write — post comments (if using git:pr)
    • issues: write — create issues (if using git:issue)

Cache Contents

  • Trivy database (vulnerability data)
  • Scan metadata
  • No credentials are cached

Exit Codes

CodeMeaning
0Success — no blocking findings
1Failure — at least one block action triggered, or fatal error