[Bug] /fork copies malformed advisor history, reports working, then child immediately 400s

Status Open
Reported on v2.1.212
Maintainer reply None cached
Activity 0 comments · opened Aug 23, 2026

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

  • /fork copied 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:

  1. Repair or coalesce the pair when the IDs match and only synthetic metadata separates them.
  2. Fork from the last known replayable point.
  3. Create a text-only continuation that excludes malformed structured tool blocks.
  4. 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

  1. Create a parent transcript containing a server_tool_use and matching advisor_tool_result separated by a synthetic isMeta user record.
  2. Run /fork <task>.
  3. Assert that Claude Code does not send an invalid child history.
  4. Assert that the fork either repairs the history, starts from a safe point, creates a text-only continuation, or returns a local recovery error.
  5. 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

View original on GitHub ↗