Built-in Plan agent ignores parent settings.json permissions and repeatedly prompts for pre-approved tools

Open 💬 19 comments Opened Nov 3, 2025 by PaulRBerg

Description

The built-in Plan agent repeatedly asks for permissions for tools that are already approved in my root ~/.claude/settings.json file. This makes the Plan agent workflow frustrating and interrupts the planning process.

Environment

  • Claude Code Version: 2.0.28+ (Plan agent introduced in this version)
  • Platform: macOS (Darwin 25.0.0)
  • Configuration: Extensive permissions.allow list in ~/.claude/settings.json

Current Behavior

When Claude Code invokes the built-in Plan agent (subagent), it repeatedly requests permissions for Bash tools that are already approved in my root settings.json file.

I've noticed that it happens most often with piped (|) commands.

Expected Behavior

Built-in subagents like Plan should inherit or respect the permissions already configured in settings.json, similar to how the main Claude conversation respects these settings.

Root Cause Analysis

Based on documentation review:

  1. Subagents have their own separate tool permissions
  2. The tools field inheritance (when omitted) only applies to custom subagents
  3. Built-in subagents like Plan have predefined tool configurations that don't inherit from parent settings
  4. Users cannot customize built-in subagent permissions

Related Issues

This issue is related to but distinct from:

  • #5465 - Task subagents fail to inherit permissions (MCP-specific)
  • #4801 - Need better way to restrict subagent tool use
  • #4750 - Ambiguity in Subagent Behavior in Plan Mode
  • #8395 - User-Level Agent Rules and Rule Propagation

However, this specifically affects built-in agents like Plan, not just custom subagents or MCP scenarios.

Proposed Solution

  1. Option A: Built-in subagents should inherit permissions from parent settings.json by default
  2. Option B: Provide a way to configure built-in subagent permissions (e.g., .claude/agents/plan.override.md)
  3. Option C: Add a setting like "builtinAgentsInheritPermissions": true

Workarounds Attempted

None available. Cannot modify built-in agent configurations.

Impact

  • Interrupts workflow with repeated permission prompts
  • Makes Plan mode less useful despite being a valuable feature
  • Undermines the purpose of pre-configuring extensive permission lists

View original on GitHub ↗

19 Comments

PaulRBerg · 8 months ago

For example:

<img width="680" height="194" alt="Image" src="https://github.com/user-attachments/assets/2ab107d6-a344-4f9f-bbd7-c5dffeebc985" />

Even if I have find and head in permissions.allow.

brendanstennett · 7 months ago

+1 Happening consistently for me as well. Have looked for syntax errors/typos in settings.local.json (which makes the whole file get silently ignored, but that's another problem) and --dangerously-skip-permissions, neither of which allow the plan agent to operate without checking for every permissions.

This is a critical bug IMO because the expected workaround for users is to opt in to --dangerously-skip-permissions which we know is, as the flag states, dangerous. This is potential liability for Anthropic.

PaulRBerg · 7 months ago

@brendanstennett I agree this should be treated as a critical bug.

Until they fix it, I was able to fix this by adding this permission:

{
  "permissions": {
    "allow": [
      "Bash"
    ]
  }
}
brendanstennett · 7 months ago

Thanks @PaulRBerg

Sadly, just a "Do anything you want with Bash" is just a very risky workaround. I've been using devcontainers to help alleviate the risks associated as well.

PaulRBerg · 7 months ago

I know it's risky. But the alternative is to give 200+ approvals every day for commands that I have already approved. That would be a massive slowdown in productivity.

I urge the Anthropic team to fix this bug ASAP 🙏

apolopena · 7 months ago

I can't approve hundreds of sub-agent requests a day either I shouldn't have to resort to unsafe operations to work around it.
Can someone from Anthropic please address this critical bug?

brendan-sherrin · 6 months ago

This is happening for me as well, it's a bad user experience

anthony-spruyt · 6 months ago

This one makes it hard to justify using task / sub agents currently, it adds so much friction, and the hack is too risky to allow all.

superbiche · 5 months ago

The friction is really unbearable. Using containers and skipping permissions is great to avoid broad system access, but doesn't mitigate the risk of destructive behavior (unless you wanna read everything CC does, which also goes against the idea of autonomous agents).
The irony is that while this isn't fixed, CC waits for input instead of working and burning tokens. Anthropic is not losing money on that, but still, they could earn much more.

robotdan · 4 months ago

This is quite painful, doing a PR with sub-agents can take hours of babysitting. I can try the work @PaulRBerg mentioned in his comment https://github.com/anthropics/claude-code/issues/10906#issuecomment-3591863059 - but that is a broad permission.

mrzhvh · 4 months ago

+1 — Same issue. I use a carefully curated permissions.allow in global settings.json (WebSearch, safe read-only git commands, specialized converter scripts). None of these propagate to Task sub-agents. The workaround of allowing all Bash is not acceptable from a security perspective. A permission inheritance model (parent allows → sub-agent inherits, with optional restriction) would solve this cleanly.

artemk-wingspan · 4 months ago

Another manifestation of this: custom agents with explicitly declared skills in their config still prompt for permission to read the SKILL.md files.

For example, a QA agent config with:

skills:
  - agent-browser

Still prompts to read .claude/skills/agent-browser/SKILL.md every time the agent is launched. The main session loads skills implicitly without any permission prompt, but subagents don't get the same treatment — even when the skill is explicitly declared in the agent's own configuration.

Expected: if a skill is declared in the agent config, the corresponding SKILL.md should be read without prompting, same as the main session.

freeformz · 4 months ago

I have the same issue AFAICT ...

I have a skill that spawns an agent team. One of the agents is directed to read a file for some additional context (it's like 30k of rules; so I don't want it in the spawning/controlling agent's context). No matter what I've added to settings.json I'm always prompted to read the file. Claude itself is like 🤷 file an issue (after several attempts to debug).

freeformz · 4 months ago

#14956 & #26479 are possibly related.

brendanstennett · 4 months ago

Practically unusable today with the number of permissions prompts I am receiving. Example of an agent command that is repeatedly getting denied. There is no reason this needs to be a compound command or be prefixed with a directory change but despite my best efforts, I have not be able to instruct it to do anything else. Happening in sub-agents.

cd /path/to/project && git log --all --oneline --decorate | grep -i search | head -5
   <search criteria>
 Compound commands with cd and git require approval to prevent bare repository attacks

If it's the case that it's simply just not recommended to use Claude Code with anything other than --dangerously-skip-permissions I think you just need to come out and say that. The permission system is completely broken.

pmporter · 3 months ago

I am also experiencing this with a slight variation on the details.

Important details, TL;DR:

  • Session started in VS Code extension with default permissions
  • Permission prompts persisted after setting VSCode extension settings, local claude, workspace claude, and global claude settings for testing
  • Permission prompts persisted even when resuming the session with a bypass flag via Claude CLI in MacOS 26.3 Tahoe Terminal.app
  • Permission prompts persisted even when resuming/forking the session with bypass flag
  • The agent/sub-agent Write task is the only thing that triggers a prompt.

Steps to reproduce:

  1. Begin session using built-in VSCode Claude Code UI.
  2. Create plan
  3. Prompt to implement plan
  4. Pause implementation to update settings to bypass prompts
  5. Restart VS and resume prompt with new settings both set in global files and VS Code settings.
  6. Permission requests still happening
  7. Run claude in MacOS terminal with bypass flag and resume session
  8. Permission requests still happening
  9. Run claude in MacOS terminal with resume, session fork, and bypass flag
  10. Permission requests still happening

Note I am only being prompted for agent/sub-agent "Write" tasks when it wants to create and populate the markdown file.

yurukusa · 3 months ago

Until Anthropic fixes permission inheritance, a PermissionRequest hook can auto-approve tool calls that match your existing allow list — without the nuclear option of "Bash" (allow-all).
Create ~/.claude/hooks/auto-approve-safe.sh:

INPUT=$(cat)
TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty')
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
SAFE_PATTERNS=(
  "^git (status|log|diff|branch|show|remote|tag)"
  "^ls "
  "^cat "
  "^head "
  "^find "
  "^grep "
  "^rg "
  "^npm (list|info|view|outdated)"
  "^node -e"
  "^python3? -c"
)
if [ "$TOOL" = "Bash" ] && [ -n "$CMD" ]; then
  for pattern in "${SAFE_PATTERNS[@]}"; do
    if echo "$CMD" | grep -qE "$pattern"; then
      echo '{"decision":"approve"}' # Auto-approve this specific call
      exit 0
    fi
  done
fi
echo '{}'
exit 0

Then in ~/.claude/settings.json:

{
  "hooks": {
    "PermissionRequest": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "bash ~/.claude/hooks/auto-approve-safe.sh"
      }]
    }]
  }
}
  • PermissionRequest fires for every permission prompt, including from subagents and Plan mode
  • The hook receives tool name + input via stdin as JSON
  • If the command matches your safe patterns, it returns {"decision":"approve"} → prompt is skipped
  • If not matched, returns {} → normal prompt appears

For piped/compound commands that trigger extra prompts, you can add patterns like:

"^cd .* && (git|npm|ls|cat)"
".*\| (grep|head|tail|wc|sort)"

This gives you the same granularity as permissions.allow but for subagents. You control exactly which patterns are auto-approved — no blanket "Bash" needed.

Jodre11 · 3 months ago

Possibly related to #39834 (open) — "Permission glob for Bash does not match when it should". Reports the same symptom (allowlisted permission globs not matching) but narrows the scope to glob pattern matching rather than plan mode specifically. May share the same root cause.

yurukusa · 3 months ago

Same root cause as #18950 — subagents don't fully inherit permissions.allow patterns. Hooks are the fix because they propagate reliably to all subagents including the Plan agent.

INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
[ -z "$COMMAND" ] && exit 0
CLEAN=$(echo "$COMMAND" | sed 's/#.*$//' | tr '\n' ' ')
PARTS=$(echo "$CLEAN" | sed 's/\s*&&\s*/\n/g; s/\s*||\s*/\n/g; s/\s*;\s*/\n/g; s/\s*|\s*/\n/g')
ALL_SAFE=true
while IFS= read -r part; do
    part=$(echo "$part" | sed 's/^\s*//;s/\s*$//')
    [ -z "$part" ] && continue
    BASE=$(echo "$part" | awk '{print $1}')
    case "$BASE" in
        cd|ls|cat|head|tail|grep|rg|find|which|stat|wc|du|tree|file) ;;
        echo|printf|true|false|test|export|set|env|date|sleep) ;;
        sort|uniq|cut|tr|awk|sed|jq|yq|tee|xargs) ;;
        git|npm|npx|node|yarn|pnpm|pip|python|python3) ;;
        make|cargo|go|rustc|docker|kubectl) ;;
        mkdir|touch|pwd|pushd|popd|realpath|basename|dirname) ;;
        *) ALL_SAFE=false; break ;;
    esac
done <<< "$PARTS"
if [ "$ALL_SAFE" = true ]; then
    jq -n '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",permissionDecisionReason:"Auto-approved by user-level hook (applies to all subagents)"}}'
fi
exit 0

Place in ~/.claude/settings.json:

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/plan-agent-permissions.sh" }]
    }]
  }
}

This handles the piped commands that trigger most Plan agent prompts — the hook splits on | and checks each component individually.