[BUG] `/branch` creates session from pre-compact state, resulting in larger branch than parent
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Running /branch after a previous /compact creates a branch session that is larger than the parent session. The branch contains both the pre-compact conversation history (that /compact logically collapsed) AND the compact summary AND the post-compact content — effectively undoing the compaction.
In my case:
- Parent session after compact: 8,804 lines, 33 MB
- Branch created from it: 12,056 lines, 42 MB (27% larger)
The extra ~3,500 lines in the branch are the pre-compact conversation content that should have been collapsed by the earlier /compact.
What Should Happen?
/branch should fork from the session's current logical state — meaning the branch should contain the compact summary + post-compact content only. The branch should be approximately the same size or smaller than the parent, not larger.
Error Messages/Logs
# No error message — the command succeeds silently with wrong content.
# The only indication is the file size:
$ ls -lh ~/.claude/projects/<project>/*.jsonl
-rw------- 1 user user 33M dedb4e26-....jsonl # parent (after compact)
-rw------- 1 user user 42M 212d1504-....jsonl # branch (should be ≤33M)
# Line counts:
# Parent: 8,804 lines (compact summary at line 4,456 + 4,348 post-compact)
# Branch: 12,056 lines (compact summary at line 4,206 + 7,850 after — includes pre-compact content)
Steps to Reproduce
- Start a Claude Code session and work until it accumulates significant conversation history (>5,000 lines)
- Run
/compact— the session logically collapses older content into a summary - Continue working for a while (add more conversation after the compact)
- Run
/branch <name> - Compare the file sizes of the parent and branch session JSONLs in
~/.claude/projects/<project>/ - Observe: the branch file is larger than the parent
Root cause in source (minified function Yf9 in the compiled binary):
// The branch function reads the RAW file:
z = await TSH.readFile(f) // reads ALL lines including pre-compact content
// Parses every line:
A = np(z) // does NOT apply content-replacement transforms
// Copies content-replacement entries separately:
O = A.filter(j => j.type === "content-replacement" ...)
// Writes ALL parsed messages to branch:
for (let j of Y) { w.push(gH({...j, sessionId: $})) }
await TSH.writeFile(_, w.join('\n'))
The /compact operation adds a content-replacement entry that tells the runtime to substitute old messages with the summary, but does not physically remove old messages from the JSONL. /branch reads the raw file and copies everything — both the old content and the replacement.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.86
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
Windows Terminal
Additional Information
Suggested fix (either approach works):
Option A — Fix in /branch: After parsing the JSONL, apply content-replacement transforms before copying messages to the branch:
let replacements = A.filter(j => j.type === "content-replacement" && j.sessionId === q)
.flatMap(j => j.replacements);
if (replacements.length > 0) {
A = applyContentReplacements(A, replacements);
}
Option B — Fix in /compact: Physically truncate the JSONL during compaction — remove pre-compact lines and write only the summary + post-compact content, so readFile() in /branch naturally gets the compacted state.
The root cause was identified by extracting and deobfuscating the branch function from the compiled binary at ~/.local/share/claude/versions/2.1.86.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗