[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

Open 💬 4 comments Opened Jun 6, 2026 by Aron-Lomner

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.

  1. Start Claude Code (v2.1.167) in manual-approve mode (default permission mode, no auto-accept/bypass).
  2. Run multiple agents/subagents concurrently, each producing commands that require approval (e.g., Bash calls not on the allow list).
  3. 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.
  4. Review the displayed command and decide to approve it.
  5. 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.
  6. 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_

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗