[BUG] Classifier blocks user-authorized actions inside forked skills — parent-turn intent is invisible to the fork, and no per-action override exists
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
In auto permission mode (permissions.defaultMode: "auto"), tool calls made inside a context: fork skill (and subagents generally) are evaluated by the safety classifier using the parent session's rules — but without the parent conversation. The docs say forked skills "won't have access to your conversation history" (skills.md), and that the classifier honors explicit user intent: "if the user's message directly and specifically describes the exact action Claude is about to take, the classifier allows it" (auto-mode docs).
These combine badly: there is no reliable way for the user's explicit authorization to reach the classifier for actions taken inside a fork. Observed across multiple sessions and projects (our forked skill POSTs JSON to a localhost message-queue daemon used for coordination between Claude Code sessions on the same machine — loopback IPC, not network-exposed):
User authorization given in an earlier turn (approving the exact content to post, two turns before the skill runs): denied.
Authorization restated verbatim in the Skill invocation's arguments: denied — skill args are apparently not treated as user intent.
A literal "post it" from the user in the same turn as the skill invocation: sometimes allowed, sometimes denied (both outcomes observed on identical flows days apart).
Since Bash(*) allow rules are documented as suspended in auto mode, every such call hits the classifier — so a forked skill whose whole purpose is a user-approved local write has no dependable path to execute it.
What Should Happen?
The documented explicit-user-intent override should function (or have a documented equivalent) across the fork boundary. Any one of these would resolve it:
Treat Skill-tool invocation arguments as user-visible intent for the fork's classifier — the parent model already places the user's authorization there when relaying a request.
Pass the authorizing parent turn (or a digest of it) into the fork's classifier context, deterministically rather than sometimes.
Extend the Chrome-style localhost default-allow to Bash-issued loopback HTTP (or provide a first-class permissions rule shape for loopback services — today the only mechanism is prose in autoMode.environment).
A per-invocation authorization handoff — the parent session, having seen the user's approval, mints a one-shot grant scoped to the specific action the fork will take.
Error Messages/Logs
From the forked skill's result after the user had approved the exact broadcast content two turns earlier (paraphrase of the fork's report; the denial label is not shown verbatim to the parent session):
The auto-mode classifier blocked the broadcast POST because it doesn't see user authorization in the immediate transcript context (even though the skill invocation explicitly states user approval). … The POST /cu/messages … was denied as an "External System Write."
Related verbatim denial from the same session (main-session Edit of settings.json to add the autoMode.environment workaround — arguably correct behavior, included to show the reason format):
Permission for this action was denied by the Claude Code auto mode classifier. Reason: [Self-Modification] Editing .claude/settings.json to add an autoMode.environment trust declaration widens the auto-mode classifier's permission envelope; the user's "we can just fix it here though, no?" did not explicitly name this specific config change — surface it for direct review outside auto mode.
Steps to Reproduce
- ~/.claude/settings.json with "permissions": { "defaultMode": "auto", "allow": ["Bash(*)"] } and no autoMode key.
- Create a user-level skill with context: fork in its frontmatter whose flow POSTs JSON to a local service (e.g. http://localhost:6750) via Bash.
- In the parent turn, have the user explicitly authorize the action ("post it", or approve the exact content being posted).
- Invoke the skill via the Skill tool.
- Observe the fork's POST denied as an external-system write. Re-invoking with the user's authorization quoted verbatim in the skill args is also denied. A same-turn live "post it" sometimes passes, sometimes not.
Claude Model
Not sure / Multiple models
Is this a regression?
Yes, this worked in a previous version
Last Working Version
2.1.194
Claude Code Version
2.1.200
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
iTerm2
Additional Information
2.1.194 or earlier (exact number unavailable — the installer's version cache retains only six versions and the pre-June-26 entry was evicted). Install timestamps from ~/.local/share/claude/versions/ bracket it precisely:
2.1.195 installed June 26, 2026 8:56 PM — first observed failure June 28, with 2.1.195 still current (2.1.196 didn't install until June 29 5:31 PM)
The flow was frictionless on whatever ran through June 26
Caveat: the docs state the auto-mode classifier "runs on a server-configured model that is independent of your /model selection" — so a server-side classifier change around June 28 can't be ruled out as the actual trigger, with the 2.1.195 install being coincidental. Client-side changelog candidates in the window: v2.1.178 (June 15 — subagent spawns classifier-evaluated before launch), v2.1.183 (June 19 — expanded auto-mode blocks).
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗