Debugging a Claude Code Security Agent: Failure Modes
Fix loops, hallucinated CWE IDs, and wrong tool calls in LLM source-code security agents. A practical Claude Code debugging field guide for engineers.
The first time you point a Claude-powered agent at a real repository and ask it to find security bugs, it usually works. The tenth time, on a gnarly monorepo at 2 a.m. in CI, it does something baffling: it greps the same directory four times in a row, reports a SQL injection in a file that does not exist, or quietly truncates its review after the third package. Building an LLM source-code security scanner is one problem; debugging one in production is a different and stranger discipline. This post is a field guide to the failure modes you will actually hit and how to diagnose them with Claude Code, the Agent SDK, and a bit of disciplined logging.
Security agents are unusually hard to debug because the thing you are checking — "did it find the real vulnerabilities?" — is exactly the thing you cannot easily verify by eye. A failed file write throws an exception. A missed authentication-bypass finding throws nothing. So your debugging strategy has to make the agent's reasoning and tool use observable, not just its final answer.
Why security agents fail differently than chatbots
A conversational assistant that hallucinates is annoying. A security agent that hallucinates is dangerous in two directions at once: a false positive wastes an engineer's afternoon chasing a non-bug, and a false negative ships an exploitable flaw with a green checkmark next to it. Both erode trust fast, and a security tool that engineers stop trusting is worse than no tool, because it manufactures a false sense of coverage.
The structural reason these agents misbehave is that source-code review is long-horizon and tool-heavy. A single pass over a service might involve dozens of grep, read_file, and git diff calls, each adding tokens and each an opportunity for the model to lose the thread. The longer the trajectory, the more the early instructions get diluted by intermediate tool output, and the more likely the agent drifts into a loop or fabricates a path it never actually read.
The three classic failure modes
Almost every bug I have chased in a Claude security agent collapses into one of three buckets. Loops are when the agent repeats a tool call with the same or trivially different arguments, often because it forgot it already ran it or because the tool returned something it did not know how to interpret. Hallucinated arguments are when it invents a file path, a line number, a CWE identifier, or a function name that does not exist in the repo. Wrong tool calls are when it reaches for the wrong capability entirely — running a code-formatter when it meant to read a file, or calling a write tool during what was supposed to be a read-only review.
Hear it before you finish reading
Talk to a live CallSphere AI voice agent in your browser — 60 seconds, no signup.
flowchart TD
A["Agent turn starts"] --> B{"Tool call valid & new?"}
B -->|Yes| C["Execute tool, log args + result"]
B -->|Repeat of prior call| D["Loop detected: inject 'you already ran this'"]
B -->|Path/arg not in repo| E["Hallucination: reject, return error to model"]
C --> F{"Finding produced?"}
F -->|Yes| G["Verify finding cites real file+line"]
F -->|No| A
G -->|Citation fails| E
G -->|Citation holds| H["Append to verified report"]
D --> A
E --> A
The reason it helps to name these explicitly is that each has a different fix. You do not solve a loop the same way you solve a hallucination. Treating "the agent is acting weird" as one undifferentiated problem is how teams end up endlessly tweaking the system prompt and wondering why nothing improves.
Diagnosing loops: make the trajectory visible
Loops are the easiest to detect mechanically because they are literally repetition. The cheapest instrumentation is to hash every tool call — name plus normalized arguments — and keep a running set per session. When you see the same hash twice, you have a loop forming. With the Claude Agent SDK you can hook the tool-execution boundary and log {turn, tool, args_hash, result_bytes} for every call, then grep the log for duplicate hashes after a bad run.
Once you can see loops, the fixes are concrete. Inject a short observation back into the context when a duplicate is detected: "You already ran grep for 'exec(' in src/ and got these results; do not repeat it." Cap the number of identical-tool repeats and force the agent to summarize what it has learned so far. Most loops are really the agent failing to register that a tool already answered its question, usually because the result was empty or noisy. An empty grep result that just says "no matches" is far more loop-inducing than one that says "no matches for 'exec(' in 14 scanned files; the directory was read successfully."
Diagnosing hallucinated arguments: verify against ground truth
Hallucinated arguments are the most dangerous because they produce confident, well-formatted findings about code that does not exist. The defense is to never trust a path, line number, or symbol the model emits — always resolve it against the real filesystem before it reaches a human. If the agent reports "SQL injection at billing/repo.py:88," your harness should open that file, confirm it has at least 88 lines, and ideally confirm the cited snippet actually appears there. When the citation fails to resolve, you do not show the finding; you feed the failure back to the model as a tool error and let it correct.
This citation-verification step is the single highest-leverage thing you can add to a code security agent. It converts a whole class of silent fabrications into loud, catchable errors. It also has a pleasant side effect: knowing its claims will be checked, and with Claude's tendency to ground itself when given a verification loop, the agent learns to read before it asserts. Hallucinated CWE IDs are a related sub-case — keep a canonical list of valid CWE numbers and titles, and reject any finding that cites one not on the list, prompting the model to pick the closest real category.
Wrong tool calls and the read-only invariant
A security review should almost never modify the code it is reviewing, yet agents with write access will occasionally try to "fix" a bug mid-review, corrupting the very artifact you are auditing. The clean solution is structural rather than prompt-based: during the review phase, only expose read-oriented tools — read_file, grep, list_dir, git_log — and physically withhold any tool that writes. The agent cannot make a wrong write call if the write tool is not in its toolset for that phase. If you do want auto-remediation, make it a separate, explicitly gated phase with its own toolset and its own human approval.
For the subtler wrong-tool problems — reaching for a generic search when a security-specific analyzer would be better — the fix is tool description quality. Claude chooses tools largely from their descriptions, so a vague "search the code" tool competes with a precise "find tainted data flows from request inputs to sinks" tool and loses to it only when the latter is described well. Invest in tool descriptions the way you would invest in API documentation; they are the agent's only map of what it can do.
Still reading? Stop comparing — try CallSphere live.
CallSphere ships complete AI voice agents per industry — 14 tools for healthcare, 10 agents for real estate, 4 specialists for salons. See how it actually handles a call before you book a demo.
Building a reproducible debug loop
The meta-lesson is that you cannot debug what you cannot replay. Record full transcripts — system prompt, every tool call, every result, the final report — for every run, keyed by a session ID and the exact commit hash of the repo. When a run goes wrong, you want to re-run it against the same commit with the same seed conditions and watch the trajectory step by step. Claude Code's transcript and logging facilities make this practical, and the Agent SDK lets you wrap tool execution so capture is automatic rather than something you remember to turn on. Keep a small corpus of "known-bad" runs as regression fixtures; when you change the prompt or tools, replay them and confirm the old failure no longer reproduces.
Frequently asked questions
What is a loop in an LLM agent?
A loop is when an agent repeatedly issues the same or near-identical tool call without making progress, usually because it failed to register that an earlier call already answered its question. In a code security agent this often shows up as repeated grep or read_file calls on the same target. The standard fix is to detect duplicate tool calls by hashing their arguments and inject a corrective observation back into the model's context.
How do I stop a security agent from hallucinating file paths?
Verify every cited path, line number, and symbol against the real repository before any finding reaches a human. Resolve the file, confirm the line exists, and ideally confirm the quoted snippet is actually present. When verification fails, return the failure to the model as a tool error so it can correct rather than surfacing a fabricated finding.
Should a code security agent be allowed to edit code?
During the review phase, no — withhold write tools entirely so the agent physically cannot modify the artifact it is auditing. If you want automated fixes, make remediation a separate, explicitly gated phase with its own toolset and human approval, so review and modification never share a context.
Why do longer reviews fail more often?
Security review is a long-horizon, tool-heavy task, and the longer the trajectory the more intermediate tool output dilutes the original instructions, increasing drift, loops, and fabrication. Chunking the work — reviewing one service or directory per bounded subagent run — keeps each trajectory short enough that the model stays grounded.
Bringing agentic AI to your phone lines
The same debugging discipline — observable trajectories, verified outputs, and tight tool scoping — is what makes CallSphere's voice and chat agents reliable enough to answer every call, use tools mid-conversation, and book real work around the clock. See it live at callsphere.ai.
Source & attribution: This is an independent, original explainer inspired by Anthropic's coverage on the Claude blog. Claude, Claude Code, Claude Cowork, Claude Opus, and the Model Context Protocol are products and trademarks of Anthropic. CallSphere is not affiliated with or endorsed by Anthropic.
Try CallSphere AI Voice Agents
See how AI voice agents work for your industry. Live demo available -- no signup required.