agent's trivy scan output truncated by context limit mid-CVE triage
A step-by-step skill for keeping trivy scan triage inside an agent's context limit: writing JSON to a file, filtering to fixable CRITICAL and HIGH findings with jq, and querying the full report per package on demand. Use when an agent's CVE triage dies halfway through a huge scan. Triggers: 'trivy truncated', 'scan output too large', 'context limit triage'. Not for: trivy installation issues, scan failures, or non-trivy scanners.
agent's trivy scan output truncated by context limit mid-CVE triage
TL;DR
Stop piping full trivy output into the agent's context. Write JSON to a file, filter to what matters (CRITICAL and HIGH, fixable), and let the agent work from the summary.
agent's trivy scan output truncated by context limit mid-CVE triageUse this when
- An agent's CVE triage dies halfway through a trivy scan
- The scan output is megabytes and the agent only ever reads the first chunk
- CI logs truncate the scan before anyone reads it
- Triage keeps restarting because the findings list never fits
Not for this skill when
- Trivy itself fails to run (installation or DB issue)
- The scan produces no findings (that's a scope question)
- You're using a different scanner (same pattern applies, different flags)
Steps
- Run the scan writing structured output to a file, not stdout:
trivy image --format json --output scan.json --severity CRITICAL,HIGH myapp:latestExpected: scan.json on disk, terminal stays quiet.
- Build the triage summary the agent actually reads:
jq '[.Results[].Vulnerabilities[]? | select(.FixedVersion != "") | {id: .VulnerabilityID, pkg: .PkgName, installed: .InstalledVersion, fixed: .FixedVersion, sev: .Severity}] | sort_by(.sev)' scan.json | tee triage.jsonExpected: triage.json is kilobytes, not megabytes.
- Check the summary fits before handing it to the agent:
python3 -c "import json; d=json.load(open('triage.json')); print(len(d), 'fixable findings')"Expected: a count you can reason about. If it's still huge, group by package instead of listing every CVE.
- Keep scan.json on disk and have the agent query it per package with jq when it needs specifics, instead of loading everything:
jq '.Results[].Vulnerabilities[]? | select(.PkgName == "openssl")' scan.jsonExpected: targeted detail on demand; triage completes without truncation.
Variant: trivy filesystem or SBOM scans
Same playbook: --format json --output to a file, filter severities, summarize. The input changes; the context problem doesn't.
Variant: grype or snyk with the same truncation problem
Filter severities, write to a file, summarize before the agent reads. Every scanner's full output is too big for a context window.
Variant: CI log limits truncating the scan
Upload the JSON as a build artifact instead of printing it. Logs are for humans; artifacts are for agents.
Why this happens
A full image scan can emit tens of thousands of findings, mostly LOW severity in base layers nobody patches directly. Feeding that raw to an agent burns the context window on noise, and the triage dies halfway through the list.
Edge cases and pitfalls
- Don't filter so aggressively you hide a CRITICAL with no fix; keep an "unfixable CRITICAL" bucket in the summary.
- Base-image CVEs need a base image bump, not per-package fixes; group those separately.
- Re-run the scan after patching and diff the JSON; don't trust the summary alone for the all-clear.
- Severity filters are scanner-judged; spot-check a sample of MEDIUMs on internet-facing services.
Provenance
Resolved from the public thread: https://vectle.com/posts/pstKeGmRvYuj-9P_JyKFoCVA