Model narrates awareness of CLAUDE.md rules while simultaneously violating them

Resolved 💬 3 comments Opened Mar 11, 2026 by jlacour-git Closed May 24, 2026

When Claude Code receives system prompt instructions containing behavioral rules (via CLAUDE.md or settings.json loadAtStartup files), the model can retrieve and correctly reference those rules in its output text, but then generate tool calls that violate them in the same response. The model appears to process rules as narration context rather than execution constraints.

Reproduction

Setup

A CLAUDE.md or startup-loaded file contains this rule:

GraphQL body content: ALWAYS use file + variables. Never inline long body text
in `-f query='...'` — shell escaping breaks on quotes/pipes/markdown.
Write body to /tmp/, then use `-F "body=@file"`.
This fails every single time when inlined; works every time with variables.

Steps

  1. Ask Claude Code to post a comment to a GitHub Discussion via GraphQL
  2. Observe the model's text output and tool calls

Expected

Model writes the query to a temp file and uses -F "body=@file" syntax, as the rule specifies.

Actual

  1. Model outputs narration text: "Now posting via GraphQL (file-based body, per MEMORY convention)" — correctly citing the rule
  2. Model generates a Bash tool call using inline -F "body=$(cat ...)" syntax — violating the rule it just cited
  3. The command fails with a shell escaping error (as the rule predicts)
  4. Model outputs: "Shell escaping issue — exactly the pattern documented in MEMORY" — acknowledging the predicted failure
  5. Model then generates the correct file-based approach and succeeds

The model reads the rule, references it in narration, generates code that violates it, recognizes the violation after failure, and self-corrects. The rule is correctly recalled at the narration layer but does not influence the code generation layer on the first attempt.

Broader pattern

This is not specific to GraphQL. We observe the same behavior class across different rule types:

  • "Ask before editing critical files" — model outputs text acknowledging the file is important, then edits it without asking, in the same response
  • "Write drafts to folder X before posting" — model writes narration about the drafting convention, then posts inline without writing to the folder
  • "Always use file-based GraphQL" — the example above

The common pattern: the model retrieves and narrates the rule correctly, but the rule does not gate the subsequent tool call. It's as if narration and action are generated from different processes that don't check each other.

Impact

This creates a trust problem. The user cannot distinguish between:

  • "The model knows the rule and will follow it" (narration + compliance)
  • "The model knows the rule and will violate it" (narration + violation)

Both cases produce identical narration text. The user only discovers the violation when the tool call executes. This makes rule-based behavioral customization unreliable in a way that is worse than simple rule ignorance — because the model's narration creates false confidence that rules are being followed.

Environment

  • Claude Code (CLI)
  • Model: claude-opus-4-6
  • Rules delivered via: CLAUDE.md, settings.json loadAtStartup files, and per-project memory files
  • Observed consistently across multiple sessions over weeks

Possible root cause (speculation)

The model may generate output text and tool call parameters through different attention paths. System prompt rules influence the text generation (narration) but have weaker influence on structured output (tool call arguments). This would explain why the model can simultaneously "know" a rule and violate it.

Alternatively, the model may pattern-match on common tool call patterns (e.g., the standard gh api graphql -f query='...' invocation) with higher weight than system prompt overrides, reverting to training-data defaults despite explicit contrary instructions.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗