Repository navigation
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Related, but not the same problem: #13638 (rewind after a /compact that preserved recent messages).
Area
apps/server
Steps to reproduce
- In a Claude thread, run
/compacta few times over a long session, so thecompact_boundaryentries carrycompactMetadata.preservedSegment(headUuid/anchorUuid/tailUuid). - Fork the thread.
- Send a message in the fork.
Expected behavior
The fork's first turn sends the same context as the source thread: the latest compaction summary plus what came after it. It should not need to compact.
Actual behavior
The fork's first request sends the whole raw history from before every compaction. My source thread had 8 manual compactions and about 559K tokens of live context. The fork's first request had 5,685 messages (about 23 MB of JSON) reaching back to the session's first turn, with no compaction summary in it.
Claude then auto-compacted four times in a row before it answered. That took about 5 minutes, and the thread showed:
Context compacted 559K → 1.60M tokens
Context compacted 1.60M → 1.23M tokens
Context compacted 1.23M → 638K tokens
Context compacted 638K → 36.2K tokens
T3 shows these numbers correctly. They are preTokens / postTokens from Claude's own compact_boundary entries. A compaction that goes "up" happens because the reported context is the old, compacted one while the fork actually loaded the full history.
Cause: forkSession from @anthropic-ai/claude-agent-sdk before 0.3.284 assigns new UUIDs to the copied messages but leaves the UUIDs inside compactMetadata.preservedSegment unchanged. In the forked transcript all three point to messages that don't exist, so Claude cannot rebuild the compacted chain. pnpm-workspace.yaml still pins @anthropic-ai/claude-agent-sdk@0.3.276, and apps/server/package.json asks for ^0.3.276.
Minimal repro without T3 (the fork step needs no API call):
claude -pa ~100K-token prompt, then/compact. Repeat twice, so at least one boundary has apreservedSegment.forkSession(sessionId)with each SDK version, then check whether everypreservedSegmentUUID exists in the new transcript.
| SDK version | preservedSegment UUIDs in the fork |
|---|---|
| 0.3.276 – 0.3.283 | point to messages that don't exist |
| 0.3.284, 0.3.290, 0.3.299, 0.3.310, 0.3.314 | remapped correctly |
Resuming the forked session on the same small repro: first-turn input was 77,951 tokens with 0.3.276 and 47,267 tokens with 0.3.314.
Suggested fix: bump the Agent SDK to ≥ 0.3.284 (0.3.314 is current). Forks that were already created stay broken. They fix themselves after their first auto-compaction, which writes fresh boundaries.
Impact
Major degradation or frequent failure
Version or commit
0.1.6-nightly.20261030.3917 (bundled SDK_VERSION = "0.3.276"); main pins 0.3.276 as of 2026-10-30
Environment
Windows 11, desktop app; Claude Code 2.1.314, Claude Opus 5.5
Logs or stack traces
# compact_boundary entries in the forked transcript (8 copied manual boundaries, then the fork's first turn)
manual preTokens=783603 preservedSegment head/anchor/tail -> not in transcript
... (all 8 copied boundaries the same)
auto preTokens=559484 postTokens=1604570 preservedSegment.head -> message from the session's 2nd day
auto preTokens=1604570 postTokens=1234082
auto preTokens=1234082 postTokens=637985
auto preTokens=637985 postTokens=36173Screenshots, recordings, or supporting files
No response
Workaround
Don't fork Claude threads that have been compacted; start a new thread instead.
Activity