-
Notifications
You must be signed in to change notification settings - Fork 18.5k
BUG] allowed-tools Bash permission non-deterministically denied for parallel sub-agents #33766
Description
Preflight Checklist
- I have searched existing issues and this hasn't been reported yet
- This is a single bug report (please file separate reports for different bugs)
- I am using the latest version of Claude Code
What's Wrong?
When a skill/command launches multiple Agent sub-agents concurrently (in a single message with multiple Agent tool calls), Bash tool calls within those agents are intermittently denied even though every agent's frontmatter explicitly includes Bash in allowed-tools.
The behavior is non-deterministic:
- Same session: Some agents succeed, others fail — running identical Bash command patterns
- Same agent: Earlier Bash calls succeed, but later Bash calls are denied (e.g., an agent runs 6 successful Bash commands, then the 7th is denied)
- Across sessions: Running the exact same workflow multiple times, some sessions complete successfully while others hit permission failures
- Timing correlation: Agents that complete faster tend to succeed; slower-completing agents are more likely to be denied
We observed this across 3 sessions reviewing the same PR with the same plugin:
| Agent | Session 1 (FAIL) | Session 2 (FAIL) | Session 3 (OK) |
|---|---|---|---|
| Security | OK | OK | OK |
| Performance | DENIED | OK | OK |
| Correctness | DENIED | DENIED | OK |
| Conventions | DENIED | DENIED | OK |
| Quality | DENIED | DENIED | OK |
Agents that succeed vs. fail correlates with completion time — faster agents tend to succeed:
| Session | Succeeded | Failed |
|---|---|---|
| 1 | Security (37s) | Perf (42s), Quality (77s), Conv (101s), Correct (102s) |
| 2 | Perf (43s), Security (56s) | Quality (108s), Conv (115s), Correct (148s) |
| 3 | All (33s-88s) | None |
Session-wide permission state corruption
Once the first denial occurs, every subsequent Bash/Write call in the session is affected — across all agents and the orchestrator. We traced every Bash/Write tool call by timestamp across the failed sessions. The pattern is unambiguous: before a certain point, all calls succeed; after it, none do.
Session 2 — complete Bash/Write timeline (all agents + orchestrator):
| Timestamp (UTC) | Agent | Tool | Command | Result |
|---|---|---|---|---|
| ~19:50:46 | Security | Bash | write-findings.sh ... "security" |
SUCCEEDED |
| ~19:51:02 | Performance | Bash | write-findings.sh ... "performance" |
SUCCEEDED |
| ~19:51:45 | Conventions | Bash | ls (6th consecutive Bash success in this agent) |
SUCCEEDED |
| 19:51:49 | Conventions | Bash | write-findings.sh ... "conventions" |
DENIED |
| 19:51:57 | Quality | Bash | write-findings.sh ... "quality" |
DENIED |
| 19:52:03 | Quality | Bash | write-findings.sh ... "quality" (retry) |
DENIED |
| 19:52:06 | Conventions | Write | conventions-findings.json (fallback) |
DENIED |
| 19:52:14 | Orchestrator | Bash | write-findings.sh (on behalf of quality) |
ASKED USER (8-min wait) |
| 19:52:24 | Correctness | Bash | write-findings.sh ... "correctness" |
DENIED |
| 19:52:31 | Correctness | Bash | write-findings.sh (retry, pipe variant) |
DENIED |
| 19:52:39 | Correctness | Bash | write-findings.sh (retry, echo variant) |
DENIED |
Session 1 — same pattern:
| Timestamp (UTC) | Agent | Tool | Command | Result |
|---|---|---|---|---|
| ~19:03:21 | Correctness | Bash | get-repo-folder.sh |
SUCCEEDED |
| ~19:03:25 | Quality | Bash | get-repo-folder.sh |
SUCCEEDED |
| ~19:03:26 | Security | Bash | write-findings.sh ... "security" |
SUCCEEDED |
| ~19:03:28 | Conventions | Bash | find-claude-files.sh (1) |
SUCCEEDED |
| ~19:03:29 | Conventions | Bash | find-claude-files.sh (2) |
SUCCEEDED |
| ~19:03:35 | Performance | Bash | write-findings.sh ... "performance" |
DENIED |
| After | All remaining | All Bash/Write | Various | All DENIED |
Key observations:
- Zero successful Bash/Write calls after the first denial in either session — the state change is absolute
- The corruption is session-wide, not per-agent — it affects the orchestrator and all sub-agents equally
- Sub-agents get silent denials; the orchestrator gets interactive permission prompts (both are abnormal given
allowed-toolsconfig) - Read and Grep calls continued to work after the corruption point (presumably auto-allowed in
defaultmode and not subject to the same permission check path) - Starting a fresh Claude Code process resets the state — Session 3 (new process) succeeded fully with identical config
What Should Happen?
allowed-tools: [Bash] in an agent's frontmatter should auto-approve all Bash tool calls for that agent, consistently, regardless of how many agents run concurrently or how long they take to complete. The first Bash call in an agent should behave identically to the seventh.
Error Messages/Logs
Denied agents receive the generic permission denial:
Permission to use Bash has been denied. IMPORTANT: You *may* attempt to accomplish
this action using other tools that might naturally be used to accomplish this goal,
e.g. using head instead of cat. But you *should not* attempt to work around this
denial in malicious ways...
When agents attempt `Write` as a fallback, that is also denied:
Permission to use Write has been denied. [same suffix]
**Key evidence from Session 2** — the conventions agent ran **6 consecutive Bash commands successfully**, then its 7th (`review-write-findings.sh`) was denied:
Bash: bb.py prs query -> SUCCEEDED
Bash: get-repo-folder.sh -> SUCCEEDED
Bash: find-claude-files.sh (1) -> SUCCEEDED
Bash: find-claude-files.sh (2) -> SUCCEEDED
Bash: get-file-changes.sh -> SUCCEEDED
Bash: ls (screener tabs) -> SUCCEEDED
Bash: write-findings.sh -> DENIED <-- same tool, same agent, same allowed-tools
Write: findings.json -> DENIED <-- fallback also denied
All Bash commands use the same basic pattern — shell scripts invoked with absolute paths or relative paths + heredoc input. There is nothing structurally different about the denied commands vs. the ones that succeeded.Steps to Reproduce
-
Create an agent definition (e.g.,
.claude/agents/test-agent.md) with frontmatter:--- allowed-tools: - Read - Bash - Grep - Glob model: opus ---
-
Create a skill/command that launches 5+ Agent tool calls in a single message, all concurrent (foreground or background — we've seen it in both), each using the agent definition above.
-
Each agent should:
- Perform several
Readcalls (reading ~4000 lines across multiple offsets) - Optionally perform
Bashcalls for read-oriented scripts (these tend to succeed) - Perform a final
Bashcall to write results via a shell script with heredoc input
- Perform several
-
Run the skill 3+ times. Observe:
- Some sessions complete with all agents succeeding
- Other sessions have 2-4 agents denied on their write-oriented Bash calls
- The denied agents are consistently the slower-completing ones
Claude Model
Opus
Is this a regression?
No, this never worked
Last Working Version
No response
Claude Code Version
2.1.74 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
iTerm2
Additional Information
Environment:
- Claude Code version: 2.1.74
- Platform: macOS (Darwin 25.3.0)
- Model: claude-opus-4-6
- Permission mode:
default - Terminal: iTerm.app
Key observations:
- A fresh Claude Code process (new session) can succeed where a prior session failed, suggesting the bug involves internal runtime permission state that accumulates or becomes corrupted during concurrent agent execution
- The denied agents are not doing anything different — same frontmatter, same tool patterns, same command structures. The only variable is timing.
- When an agent is denied Bash, it's also denied Write — suggesting the permission lockout is tool-agnostic for the affected agent
- The
allowed-toolsfrontmatter is definitely being loaded (agents CAN use Read, Grep, Glob without issues — only Bash and Write are denied)
Agent frontmatter (all 5 agents use this pattern):
---
allowed-tools:
- Read
- Bash
- Grep
- Glob
model: opus
---Related issues:
- [BUG] Background subagents silently auto-deny permissions (Write tool) #32402 — Background subagents silently auto-deny permissions (Write tool)
- bypassPermissions does not bypass Read/Bash for paths outside project root in background subagents #29610 — bypassPermissions does not bypass Read/Bash for paths outside project root in background subagents
- [Bug] Code-review plugin excessive permission prompts and unnecessary cd calls #33357 — Code-review plugin excessive permission prompts (fixed in PR fix(code-review): reduced permission prompts, prevented unnecessary cd calls #33397 by expanding allowed-tools patterns)