Custom session title overridden by AI-generated title; /resume forks duplicate custom titles onto new session IDs
Environment
- Claude Code v2.1.173, Linux (Ubuntu, kernel 6.17), zsh
- Interactive CLI sessions
Summary
Two related problems make named sessions effectively unfindable in the /resume picker:
1. AI-generated title displayed instead of custom title.
After naming a session (e.g. "Feature A"), an ai-title entry is appended to the session .jsonl after the custom-title entry. The resume picker then shows the AI title, so searching for the custom name finds nothing. The user reasonably concludes the session was lost, although the file is intact on disk with the custom-title recorded.
Tail of the affected session file shows the ordering (names redacted):
{"type":"custom-title","customTitle":"\"Feature A\"","sessionId":"<uuid>"}
{"type":"ai-title","aiTitle":"<auto-generated summary title>","sessionId":"<uuid>"}
{"type":"agent-name","agentName":"\"Feature A\"","sessionId":"<uuid>"}
2. Custom titles bleed onto forked sessions.
Every /resume forks the conversation into a new session ID and re-stamps the old custom title onto the fork. In one project directory the same custom title appears on 3 different session files (name "B" on 3 sessions — including a brand-new session started fresh after /clear — name "C" on 3, name "D" on 2). The picker fills with duplicate names pointing at fork copies, burying the original named session.
Steps to reproduce
- Start a session, do some work, name it (rename/custom title).
- Keep working until an AI title is auto-generated, then exit.
- Run
/resume— the session is listed under the AI title, not the custom name. - Resume any named session, exit, and
/resumeagain — the custom name now appears on multiple session entries (original + forks).
Expected
- Custom title always wins over AI-generated title in the picker.
- Forked/resumed sessions should not duplicate the custom name, or the picker should collapse fork chains.
Minor related issue
Quotes in the rename argument are stored literally: naming a session "Feature A" (quoted) stores the title including the quote characters.
Showing cached comments. Read the full discussion on GitHub ↗
4 Comments
Confirming part 2 (title duplication across
/resumeforks) on v2.1.212, Linux, with an extra data point: the picker interactions also leave title-only ghost session files behind.After one working session yesterday (which involved the agent view / backgrounding),
/resumenow shows three entries with the same AI-generated title:Inspecting the
.jsonlfiles in~/.claude/projects/<project>/:/resumepicker navigation, it contains only two metadata lines and zero messages:``
``{"type":"ai-title","aiTitle":"Créer plugin Claude Code pour agents dev","sessionId":"64d08439-..."}
{"type":"agent-name","agentName":"Créer plugin Claude Code pour agents dev","sessionId":"64d08439-..."}
A second ghost from the same evening (872 bytes) contains the same two lines repeated 4×, nothing else.
Side effect worth noting (relates to #68062): the fork broke in-flight background task tracking. A
task-notificationrecorded before the fork pointed to/tmp/claude-1000/<project>/<old-session-id>/tasks/<task-id>.output; after the fork,TaskOutputon that task id returnedNo task found with ID: <task-id>— the task registry appears to be keyed by session id, so forks orphan running tasks and their UI status line silently disappears.Happy to provide the (redacted) session files if useful.
Confirming part 2 on macOS, v2.1.220 — with a version bisect that narrows it down, and one correction: the trigger is
/new, not/resume.What the transcripts show
When a new session is created, the previous session's title record is written as line 1 of the new session file, before any user message exists:
Because the session now already carries a title, no
ai-titleis ever generated for it — so the borrowed name is permanent. The app then re-stamps that same record into the transcript roughly once per turn: 17 identical records in a 400-line live file, 53 and 243 in older ones.Version bisect
Grouping every session in
~/.claude/projects/**by theversionfield of its records, and counting sessions whose first title record precedes their first real user message:| CLI version range | sessions created via
/new| inherited a title ||---|---|---|
| 2.1.156 → 2.1.202 (9 Jun – 8 Jul) | 21 | 0 |
| 2.1.204 → 2.1.220 (8 Jul – today) | 52 | 26 |
First affected versions are 2.1.204 / 2.1.207; nothing at all in the month before. (Zero counts inside individual later versions just mean the preceding session had not been given a title yet, so there was nothing to copy.)
The trigger is easy to misdiagnose
/newwrites itself into the transcript under its legacy name:<command-name>/clear</command-name>. In my data 75 session files contain a/clearcommand record and exactly 1 contains/new, while my typed-prompt history shows/clearlast used in April 2026 and/newused 142 times since. So the record name and the command name disagree, which makes this look like it originates from/resumeor/clear.Breakdown of 43 affected sessions by how the new session id was created — same mechanism in all cases:
/new— 21/branch— ~5 (these at least get a(Branch)/(fork)suffix)/compact— 1–2Workaround
Quitting and relaunching
claudeinstead of using/newis clean: of 205 sessions started by a plain launch, none inherited a name.For anyone who wants their picker back: deleting every title record whose value equals the line-1 value, in sessions where a title record precedes the first user message, restores the fallback to each session's own first message. Across 29 such sessions that removed 847 records and cut my worst name collision from 17 sessions down to 6. Worth guarding two cases — recurring/scheduled tasks, where the repeated name is deliberate, and sessions whose own first message is a
/compactcontinuation stub, where there is nothing better to fall back to.Confirming this pattern from a different angle — a long-lived recurring background job, not just a single
/resume.I have one named background job that's been backgrounded/resumed repeatedly over ~2.5 months (May → August). Every restart forks a new session ID, replays the original opening prompt, and carries the same job name forward — but there's no link back to the prior session at all. Result: 5+ separate session-list entries, all showing the identical name, with zero indication of which is current versus superseded, or that they're related at all.
This is the same root cause as this issue (fork-on-resume duplicates the title onto a new session ID) — it just compounds badly over time for anything that gets backgrounded/resumed repeatedly rather than once. Confirmed directly in the transcripts: the old session's last entry is literally
"Backgrounding after the current tool finishes…", and the new session's first entries areai-title/agent-namerecords carrying the identical name forward — so the harness clearly has the parent session ID at fork time, it's just not surfaced anywhere in the session list.Related: #70373, #83971, #76493 — all describe the same fork-on-background/resume behavior from different angles (context loss, orphaning, task-list reset). Might be worth tracking as one root cause rather than four separate symptoms.
Adding an observation that may help narrow this down: we see the same fork-into-new-session-ID behavior (near-full transcript duplication) apparently triggered by interruption, not
/resumeor/clear.Environment: Claude Code v2.1.222 (some files from v2.1.219/v2.1.221), Claude Desktop (Code tab), Windows 11 Pro build 26200.
[Request interrupted by user], and a new file with a new session ID started 9 s – 2.5 min later (local-time pairs: 12:31:00→12:31:09, 12:42:02→12:42:13, 13:00:59→13:03:31, 14:03:11→14:03:25, 17:44:12→17:44:23, 22:32:10→22:32:59, 22:33:14→22:33:50).custom-title→mode→queue-operation, while a genuinely new session starts withqueue-operationand has neither.custom-title.Caveat:
[Request interrupted by user]records can also be produced without user action (#78915, #70958, #84346), so this is correlation, not proven causation — but 7/7 anomalous splits immediately followed an interrupt record.Possibly the same underlying resume/fork machinery as #82969, #76493, #80427, #77649. Practical impact of the duplication: transcript-based tooling double-counts sessions, and
cleanupPeriodDays(default 30) deletes fragments per-file, punching holes in long conversations (#62959 / #63904).