ESC during tool execution is reported to the assistant as "rejected"
ESC during tool execution is reported to the assistant as "rejected"
Summary
When the user presses ESC to interrupt a tool call that is actively running in Claude Code CLI,
the local UI correctly shows Interrupted · What should, but the message delivered to the assistant side uses different vocabulary:
Claude do instead?
The user doesn't want to proceed with this tool use. The tool use was rejected (eg. if it was a file edit, the new_string was NOT written to the file). STOP what you are doing and wait for the user to tell you how to proceed.
This mismatch causes the assistant to report to the user that they
"rejected" the action, when in reality the user only interrupted it. During a long debugging session
where this happened, the assistant spent multiple turns explaining to the user that "the user
rejected the tool use", which the user found surprising: they had only pressed ESC, not actively
denied anything.
Environment
- Claude Code CLI version:
2.1.104 (Claude Code) - Model: Opus 4.6 (1M context) with max effort
- OS: Linux 6.6.87.2-microsoft-standard-WSL2 (WSL2)
- Shell: bash
- Relevant flags:
--dangerously-skip-permissions(so no permission prompts were involved — the
behavior reproduces without them)
Reproduction steps
- Start a Claude Code CLI session (with or without
--dangerously-skip-permissions).
- Ask the assistant to run a long Bash command that gives you time to interrupt, for example:
````
echo start && sleep 20 && echo done > /tmp/interrupt-test.log
- While the Bash tool is actively running (during the
sleep 20), pressESConce. - Observe that the local UI shows, under the collapsed Bash block:
````
⎿ Interrupted · What should Claude do instead?
- Ask the assistant to report, verbatim, the message it received from the harness after your
ESC.
It will quote the "was rejected / STOP what you are doing" text shown above.
Expected behavior
The message delivered to the assistant should match the vocabulary shown to the user locally:
- Use the word "interrupted", not "rejected".
- Drop or soften the imperative "STOP what you are doing", which implies the user actively wants the
assistant to halt all activity.
- Ideally, keep the "rejected" vocabulary as a separate code path for the case where the user
explicitly denies a permission prompt, so the two distinct user actions (interrupt vs deny)
produce distinct messages to the assistant.
Actual behavior
Both cases — interruption of a running tool and explicit permission denial — appear to deliver the
same "rejected" message to the assistant. This makes the two user actions indistinguishable from the
assistant's perspective, which causes the assistant to misrepresent what the user did.
During the session that prompted this issue, we verified empirically that a different case —
pressing ESC while the assistant is still generating text (before any tool call has launched) —
correctly delivers [Request interrupted by user] to the assistant. So the harness already supports
a distinct "interrupted" vocabulary in one path, but not in the tool-interruption path.
Empirical evidence (three data points from the same session)
| User action | Local UI shows | Assistant receives |
|-------------------------------------------------|---------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ESC during assistant text generation | (not captured locally, but user reported pressing ESC while the assistant was streaming tokens) | [Request interrupted by user] followed by any text the user typed afterwards |
| ESC during an actively running Bash tool call | ⎿ Interrupted · What should Claude do instead? | The user doesn't want to proceed with this tool use. The tool use was rejected (eg. if it was a file edit, the new_string was NOT written to the file). STOP what you are doing and wait for the user to tell you how to proceed. |
| No ESC (control) | Normal output | exit_code=0 and stdout as expected |
All three cases were reproduced multiple times during a single session on 2026-04-13 with the
versions and environment listed above.
Impact
This is not a show-stopping bug, but it creates avoidable friction in human-assistant collaboration:
- The assistant may tell the user "you rejected this action" when the user only interrupted, which
erodes trust.
- The imperative "STOP what you are doing" can cause the assistant to over-correct and disengage
from related follow-up tasks that the user would have wanted it to continue.
- Reproducing and diagnosing the mismatch took roughly 30 minutes of back-and-forth during an
otherwise productive session, because the mismatch is not obvious from either side alone (the
user sees only the "Interrupted" side; the assistant sees only the
"rejected" side).
Proposed fix
Change the harness message delivered to the assistant when a tool is interrupted via ESC during
execution, to something that matches the local UI and avoids the imperative:
[Tool use interrupted by user during execution] The user pressed ESC. The tool did not complete. You may continue with other actions or ask the user what to do next.
Optionally, keep the current "rejected" message as a separate path exclusively for explicit
permission denials (clicking Deny on a permission prompt), so the two cases become semantically
distinct for the assistant.
---
Drafted by Opus 4.6 With Max Effort, authorized by the user.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗