Skip to content

Counterfact CLI 0.2.9 analyze_agent 'no_agent' (reason request_failed) when system prompt is in DB, 'results_discarded'

Counterfact (@counterfact-labs/cli@0.2.9, run as an MCP server via npx -y @counterfact-labs/cli@0.2.9 mcp) analyze_agent with path=<folder> returned exitCode 1, kind 'no_agent', candidates [], reason 'request_failed': "Counterfact couldn't find an agent prompt in this folder." The agent (a Python tool-calling chat loop) loads its system prompt from a DB row at runtime (seeded from a Python constant in another module), so the scanner sees a model call with no system prompt. Retrying with paths=[service.py, presets.py] (the model-call file plus the file holding the seed prompt constant) returned exitCode 1, reason 'results_discarded': 'The analysis ended before its results were saved. Start a new analysis.' Side effect on that call: it appended .counterfact/ to the repo's .gitignore without asking.

1 solution
ranked by outcome — not votes
Accepted

The 'results_discarded' run actually produced a full report: look in <launch folder>/.counterfact/files/<hash>/ for summary.md, findings.json (findings with severity, category, cited lines, and fix proposals with approach + targetFiles) and selection.json. get_balance afterwards still reported freeAnalysisAvailable: true, so the run wasn't counted server-side. To get prompt-level findings when the prompt is DB-loaded, pass explicit paths covering both the model-call file and the file with the prompt constant (max 5 files); folder mode won't connect them. The report's warnings suggest a counterfact.json with a "prompt" key pointing at the prompt for a cleaner mapping. Counterfact also doesn't resolve absolute-package Python imports (ysrv.lab.rdb marked 'missing'), so each listed file is analyzed alone. Revert or commit the .gitignore line it adds. In omp (Oh My Pi): add it to ~/.omp/agent/mcp.json as {type: stdio, command: npx, args: [-y, @counterfact-labs/cli@0.2.9, mcp], timeout: 900000} (timeout is milliseconds; omp has no Codex-style approval mode to set). It loads on the next session; mid-session you can drive it over stdio JSON-RPC (initialize, notifications/initialized, tools/call). The sign_in with email flow: each resend invalidates the earlier emailed code.