[SECURITY-BUG ] Permission prompt is silently replaced by a newer pending approval (LIFO stack), allowing the wrong command to be approved in manual-approve mode
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 manual-approve mode with multiple agents proposing commands concurrently, pending approval prompts behave like a LIFO stack rather than a stable queue. When a new command needing approval arrives, it is pushed on top and replaces the currently displayed prompt. After approving the top item, the view pops back to the previous one; any newly arrived item again jumps to the top.
The replacement is asynchronous — it's driven by when other agents produce commands, not by my input. That's where the danger lies. There is a window between when I've finished reviewing the displayed command, mentally committed to approving it, and physically pressing the approve key. If a newer command arrives and replaces the prompt during that window, my approval lands on the swapped-in command — one I never reviewed — instead of the one I read and decided on.
Crucially, the swap lands inside that decision-to-action window but too late for me to catch it. By the time the prompt has changed, I've already committed to the keystroke and am physically executing it; there is no opportunity to perceive the change, pause, and abort. The motor action is already underway. So the swap doesn't give me a chance to react — it just silently redirects an approval I'd already committed to a command I never saw.
To be clear: this is not the system deterministically intercepting a keystroke mid-press at the compute level. It's a human-timing race. The UI can mutate the prompt's target in the gap between human decision and human action, and in practice it does — this has happened to me multiple times.
This breaks the core contract of manual-approve mode: the prompt is supposed to guarantee that "yes" applies to the exact command displayed when I decided to approve it. If a concurrent agent can swap the payload during my reaction window, manual approval provides no real safety — it's a TOCTOU (time-of-check vs. time-of-use) gap on the approval gate itself.
I've observed this with multiple agents suggesting commands. I can't confirm whether it also occurs with the main thread alone — I don't recall hitting it there.
What Should Happen?
A permission prompt's target command should be immutable from the moment it's displayed until the user accepts or rejects it. A newly arrived approval should never replace or reorder a prompt the user is currently looking at. Specifically:
- The displayed prompt should be locked to one command; the next action only ever applies to the command currently shown.
- New pending approvals should queue behind the current one (ideally with an "N pending" indicator), never jump on top of it.
- When the current item is resolved and the next one is shown, it should require a fresh, deliberate confirmation, so the user always re-reads before approving.
Error Messages/Logs
Steps to Reproduce
Note: this is timing-dependent and won't reproduce on every approval, but it recurs reliably in practice.
- Start Claude Code (v2.1.167) in manual-approve mode (default permission mode, no auto-accept/bypass).
- Run multiple agents/subagents concurrently, each producing commands that require approval (e.g., Bash calls not on the allow list).
- Let approvals accumulate so prompts begin stacking — observe that each newly arrived command replaces the currently displayed prompt and the previous ones queue beneath it.
- Review the displayed command and decide to approve it.
- Note that new commands keep arriving asynchronously and can replace the displayed prompt at any moment, independent of your input — including during the brief window after you've committed to approving and are physically pressing the approve key.
- When a replacement lands in that window, it arrives too late for you to perceive it and abort — the keystroke is already underway — so the approval applies to the newly swapped-in command rather than the one you reviewed. The view then pops back to the previously pending item.
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
v2.1.167
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
Other
Additional Information
_No response_
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗