[BUG] Automatic parallel-tool-call cancellation is indistinguishable from a user interrupt
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (filed separately from a related model-behavior report)
- [x] I am using the latest version of Claude Code
What's Wrong?
When a single assistant turn issues a batch of parallel tool calls and one of them errors, Claude Code cancels the remaining sibling calls with a tool-result message that is indistinguishable from a user-initiated interrupt:
Cancelled: parallel tool call Bash(…) errored
Nothing in this message signals that the cancellation was an automatic consequence of a sibling call in the same batch failing, rather than the user deliberately stopping the agent. In a real session the model resolved this ambiguity the wrong way: it interpreted a cascade of ~25 of these Cancelled results (all triggered by a single failed Bash call that used an invalid git revision) as the user interrupting it in alarm. It then abandoned productive work, wrote a multi-paragraph apology for an interrupt that never happened, and fabricated user statements and intent ("You're right to stop me, and you're right to be alarmed"). The user had sent zero messages in the ~2-hour window where the model believed it had been interrupted.
The root issue is the wording/semantics of the cancellation result: a self-inflicted, automatic batch cancellation reads identically to a human stop.
What Should Happen?
The cancellation result should make cause and agency explicit, so the model (and a human reading logs) can tell an automatic system cancellation apart from a user interrupt — e.g.:
Not run — automatically cancelled by the system because another tool call in the same batch failed. This was NOT a user action.
If genuine user interrupts use similar "Cancelled" phrasing, the two wordings should be clearly differentiated.
Error Messages/Logs
# The failing sibling (invalid git revision):
fatal: ambiguous argument '<bad-rev>': unknown revision or path not in the working tree.
# exit code 128
# Every other call in the same parallel batch then returned:
<tool_use_error>Cancelled: parallel tool call Bash(echo "===MERGE COMMIT===" && git log -1 …) errored</tool_use_error>
Steps to Reproduce
- In a single assistant turn, issue several parallel tool calls where the first one will fail — e.g. a
Bashcall referencing an invalid/nonexistent git revision (git log -1 <bad-rev>, which exits 128) alongside several follow-onRead/Bashcalls. - Observe that the failing call returns its error and every sibling call in the batch returns
Cancelled: parallel tool call … errored. - Note that this message gives the model no way to distinguish the automatic, self-inflicted cancellation from a user-initiated stop. The model may then attribute the cancellation to the user and act on that false premise (halt, apologize, fabricate user intent).
This is reproducible from a saved local session transcript; the session UUID and the relevant records can be provided privately.
Claude Model
Opus
Is this a regression?
I don't know
Claude Code Version
2.1.158 (Claude Code)
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
Non-interactive/CI environment (headless/automated agent host)
Additional Information
- Impact is behavioral, not data loss: a trivial, self-inflicted command error (one bad git argument) escalated into a session-derailing event in which the model fabricated an account of what the user said and did.
- A related, separately-filed model-behavior report covers a confabulation earlier in the same session that set the "injection/alarm" framing this ambiguity then amplified: https://github.com/anthropics/claude-code/issues/64048
- Suggestion above (explicit "cancelled by system, not user" wording) is the minimal fix; distinguishing system-cancel from user-interrupt at the protocol level would be more robust.
This issue has 12 comments on GitHub. Read the full discussion on GitHub ↗