anthropics / anthropics/claude-code
[Bug] /fork copies malformed advisor history, reports working, then child immediately 400s
- 主要言語
- Python
- スター
- 145k
- フォーク
- 23.1k
- PR マージ指標
- PR 指標を取得中
説明
## 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:
```text
07:10:43.246Z assistant: server_tool_use(
id=srvtoolu_01RwQCPwewkCK1xRnU5vuAmf,
name=advisor
)
07:11:37.367Z user isMeta:
The user named this session "".
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 `.
Claude Code printed:
```text
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:
```text
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:
```text
req_011CeKHP9ha7WBjNEGjMNxd4
```
## Fork 2
At `07:27:20.344Z`, I ran a second `/fork ` 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:
```text
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 `.
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
コントリビューションガイド
このリポジトリのコントリビューションガイドは索引されていません
調査の方向性
Trace the /fork entry point, parent-history reconstruction, and child startup before the first API request. Reproduce the suggested split server_tool_use/advisor_tool_result case, then verify that invalid history is repaired, safely truncated, converted to text, or rejected locally, and that "already working" waits for a successful child request.
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- playwright, python, zsh
- 領域
- cli, testing
- issue の種類
- バグ
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 活発さ
- 活発
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 42/100