The corrected resume logic only runs when CLAUDE_CODE_RESUME_INTERRUPTED_TURN is set.
What
When history is rebuilt to resume an interrupted turn, tool results that were only synthesized by a shutdown are no longer treated as answers, so the underlying tool call is seen as still pending.
Details
- the unwind pass is called with a new option
shutdownUnwindResultsDoNotResolve: !0 - the affected messages are user messages with
interruptedByShutdown === !0that contain a tool_result block; these no longer resolve their tool_use and are dropped from the rebuilt list - the transcript scan for an unresolved tool_use skips those same messages, so a synthesized result cannot mask a genuinely unresolved tool use
- that scan was split into a pure over-messages helper,
findUnresolvedToolUseInTranscript, with I/O, warn logging and try/catch left in the async wrapper - consecutive user messages are no longer merged if either was interrupted by shutdown, and the tail-scan for the last live turn skips shutdown-interrupted content
- the user-rejected tool denial path now records
interruptedByShutdownfrom the abort signal - the whole path is reached only under the
CLAUDE_CODE_RESUME_INTERRUPTED_TURNenvironment variable
Evidence
shutdownUnwindResultsDoNotResolve, findUnresolvedToolUseInTranscript, interruptedByShutdown
Strings lifted out of the shipped bundle, so the claim above can be checked against them.
Names in the bundleCLAUDE_CODE_RESUME_INTERRUPTED_TURN