[BUG] ExitPlanMode denied under --dangerously-skip-permissions while EnterPlanMode is auto-approved
Bug Description
--dangerously-skip-permissions (and bypassPermissions mode) auto-approves EnterPlanMode but denies ExitPlanMode. This creates a one-way trap in --print mode: Claude enters plan mode but can never exit it, gets stuck, and the subprocess ends without implementing anything.
Expected Behavior
Either:
- Both auto-approved under
--dangerously-skip-permissions(preferred — plan mode improves output quality, and there's no interactive user to approve the exit), or - Both denied (so Claude never enters a state it can't exit)
Actual Behavior
EnterPlanMode: auto-approved (permissionMode changes to"plan")ExitPlanMode: denied with{"is_error": true, "content": "Exit plan mode?"}ExitPlanModeappears inpermission_denialsin the result
Reproduction
Minimal repro (requires jq):
echo '{"type":"user","message":{"role":"user","content":"You MUST enter plan mode first. Plan a hello world python script. Then exit plan mode and implement it."}}' \
| claude -p \
--dangerously-skip-permissions \
--input-format stream-json \
--output-format stream-json \
--verbose \
--no-session-persistence \
2>&1 \
| jq -c 'select(
(.type == "system" and .subtype == "status" and has("permissionMode")) or
(.type == "user" and (.message.content | type == "array") and (.message.content[0].is_error == true)) or
(.type == "result" and has("permission_denials"))
)'
Output (3 lines — enter succeeds, exit denied, denial confirmed):
{"type":"system","subtype":"status","status":null,"permissionMode":"plan",...}
{"type":"user","message":{"role":"user","content":[{"type":"tool_result","content":"Exit plan mode?","is_error":true,...}]},...}
{"type":"result",...,"permission_denials":[{"tool_name":"ExitPlanMode","tool_input":{"plan":"..."}}]}
Impact
This affects any claude -p subprocess workflow where Claude's CLAUDE.md instructions encourage using EnterPlanMode for non-trivial tasks. The subprocess enters plan mode (following instructions), gets stuck, and returns without implementing anything.
Current workaround: --disallowedTools "EnterPlanMode" "ExitPlanMode" — but this removes planning capability entirely rather than allowing it to work headlessly.
Environment
- Claude Code version: 2.1.42
- Platform: macOS (Darwin 25.2.0)
- Model: claude-opus-4-6
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗