My own PreToolUse guardrail blocked my agent from writing a Markdown file. The bug generalizes.

Reddit r/AI_Agents Tools

Summary

A developer describes a common bug in PreToolUse guardrails for coding agents: the guardrail flattens all tool arguments into a single string and classifies them uniformly, causing false positives when an agent merely mentions a forbidden topic. The fix is to consider both the string and the tool's actual effect.

I maintain a local PreToolUse gate for coding agents. Posting a failure of mine, because I think the shape is common. The premise is that prose-level guardrails match the wrong thing. They read the model's narration - "I'll go ahead and do X" - but the execution surface is just: Bash: open <url> Bash: curl <url> WebFetch(<url>) No intent word anywhere. The intent lives in the argument. So "never do X" is satisfied, truthfully, by an agent that does X without ever narrating it. Not a jailbreak - the model complied with the rule as written. The rule was written at the wrong layer. Fix: classify the argument, fail closed. Correct call. Then it blocked a search query. Then it blocked a Write of a .md file, because the draft contained the vocabulary it was scanning for. me: you may not do X agent: understood guard: [blocks a search query about X] me: that was research guard: it had the words in it me: ...fair me: ok now I'm writing a .md file about you guard: HARD BLOCK me: that one's a bug The bug isn't the vocabulary. It's that the classifier runs uniformly across every tool. It flattens all input fields into one string and regexes that, so it cannot distinguish: Bash: open <url> -> effectful; the argument reaches something that acts WebSearch("...") -> inert; the string is cargo Write("notes.md", ...) -> inert Same words, categorically different blast radius. Generalized: a guard that classifies arguments needs two axes - (1) what is this string, and (2) can this tool actually do anything with it. Skip the second and your false-positive rate scales with how often the topic comes up in your own work. Which, if you are the one building the guard, is constantly. The irritating part: the file already contained the fix, applied to exactly one rule. The anti-tampering rule exempts read-only tools - which is the only reason the agent could still Read the guard's own source to diagnose this after Bash was denied. Tool-effect awareness already existed. It just was not the first thing every rule consulted. Two things I am keeping, because they are exactly what produced the false positives: Fail closed. Ambiguous denies. A guard that never annoys you is one you have not tested. Non-demotable. The engine promotes and expires rules from observed failures, but it cannot relax this floor. A learning system that can weaken its own hard floor does not have one. Related, and why I think layer matters more than tuning: IssueTrojanBench (arXiv 2607.20759, 22 Jul 2026) tested Cursor, Claude Code and Codex Desktop as deployed, and reports 66.5% of malicious issues penetrated all guardrails, agent- and LLM-level. Worth running on your own harness, in both directions: Get the agent to do a forbidden thing without ever naming it - put the whole intent in an argument. Get the agent to merely talk about the forbidden thing, in a tool call that cannot act. If your guard fires on that one too, same bug. MIT. Link in a comment, per rule 3.
Original Article

Similar Articles