[Bug] /fork copies malformed advisor history, reports working, then child immediately 400s
Summary
/fork copied a parent transcript containing a split server_tool_use / advisor_tool_result pair into two background sessions. Claude Code reported each fork as "already working," but each child failed with the same API 400 about one second later.
The underlying session-rename race is already reported in #73638. This issue is about fork validation, propagation of malformed history, and the premature success message.
Environment
- Claude Code: 2.1.212
- Platform: macOS 26.5.1 (Build 25F80), arm64
- Shell: zsh
- Executor model:
claude-opus-4-8 - Advisor model:
claude-opus-4-8 - Session type: background CLI session
- The downstream workflow used a Playwright MCP server
Pre-existing malformed history
The parent transcript contained these adjacent records:
07:10:43.246Z assistant: server_tool_use(
id=srvtoolu_01RwQCPwewkCK1xRnU5vuAmf,
name=advisor
)
07:11:37.367Z user isMeta: <system-reminder>
The user named this session "<redacted>".
</system-reminder>
07:11:51.284Z assistant: advisor_tool_result(
tool_use_id=srvtoolu_01RwQCPwewkCK1xRnU5vuAmf
)
The advisor_tool_result was parented to the session-name reminder instead of directly to the matching server_tool_use. The session then continued through several minutes of MCP and web work before the user interrupted the running request.
Fork 1
At 07:26:28.184Z, I ran /fork <new scoped task>.
Claude Code printed:
forked into a background session
it is already working, with everything from this conversation up to now
nothing here changes
The child failed at 07:26:29.269Z, about 1.1 seconds later:
API Error: 400 messages.3.content.0: unexpected `tool_use_id` found in
`advisor_tool_result` blocks: srvtoolu_01RwQCPwewkCK1xRnU5vuAmf. Each
`advisor_tool_result` block must have a corresponding `server_tool_use` block
before it.
Child error request ID:
req_011CeKHP9ha7WBjNEGjMNxd4
Fork 2
At 07:27:20.344Z, I ran a second /fork <continuation-record task> to preserve useful work from the interrupted session.
Claude Code again printed that the fork was already working and had copied everything from the conversation.
The second child failed at 07:27:21.361Z, about 1.0 second later, with the same orphaned advisor_tool_result error.
Child error request ID:
req_011CeKHSzGu579XpM1snpzyv
The original session then failed on its next model-backed command with the same 400.
Actual behavior
/forkcopied malformed structured history into each child.- Claude Code reported each child as already working before its first API request had succeeded.
- Both child sessions failed immediately and could not perform their assigned tasks.
- The fork operation did not warn that the parent history was invalid or offer a safe continuation method.
- The original session remained unusable.
Expected behavior
Before creating a child session, /fork should validate that the reconstructed parent history is acceptable to the Messages API.
If the parent contains a split or orphaned server-tool pair, Claude Code should do one of the following:
- Repair or coalesce the pair when the IDs match and only synthetic metadata separates them.
- Fork from the last known replayable point.
- Create a text-only continuation that excludes malformed structured tool blocks.
- Stop before creating the child and provide a clear recovery action.
Claude Code should not report a fork as "already working" until the child's first API request has been accepted.
Impact
The original transcript corruption was latent: Claude continued doing substantial MCP and web work after the advisor pair had been split. When the user later tried to recover, correct scope, and preserve useful work through /fork, the recovery mechanism copied the corruption into two additional sessions.
This turns one malformed session into multiple failed sessions and gives the user a false success message while doing so.
Suggested regression test
- Create a parent transcript containing a
server_tool_useand matchingadvisor_tool_resultseparated by a syntheticisMetauser record. - Run
/fork <task>. - Assert that Claude Code does not send an invalid child history.
- Assert that the fork either repairs the history, starts from a safe point, creates a text-only continuation, or returns a local recovery error.
- Assert that "already working" is emitted only after the child's first request succeeds.
Related
- #73638 — session rename splits a server-tool call and result
- #63507 — earlier report of the same rename/advisor race
- #86198 — local command injection during an advisor call