/rename title lost on abnormal exit — stat-log index not synced from JSONL
Bug Description
When a session is renamed via /rename, the custom title is written to the JSONL file as a custom-title entry, but is not persisted to the stat-log index unless the session exits normally (double Ctrl+C). If the terminal is closed, the machine shuts down, or the process is killed, the custom title is lost from the index and claude -r <name> can no longer find the session.
The data is still in the JSONL — only the index lookup is broken.
Steps to Reproduce
- Start a session:
claude - Rename it:
/rename mytest - Close the terminal window (or
killthe process, or shut down the machine) - Try to resume:
claude -r mytest→ not found - The session can only be resumed by UUID
Root Cause (from source analysis)
Title storage: /rename appends a {"type":"custom-title","customTitle":"mytest","sessionId":"..."} entry to the JSONL immediately — this works fine.
Title lookup (IU function): claude -r mytest searches the stat-log index, not the JSONL directly:
async function IU(query, opts) {
let statFiles = await getStatFiles();
let { logs } = await readStatLogs(statFiles, 0, statFiles.length);
let matches = logs.filter(log => {
let title = log.customTitle?.toLowerCase().trim();
if (!title) return false;
return opts.exact ? title === query : title.includes(query);
});
// ...
}
Title indexing: The stat-log index gets customTitle populated during session shutdown:
// Only runs during normal exit
let lastTitleLine = lines.findLast(l => l.startsWith('{"type":"custom-title"'));
if (lastTitleLine) {
let title = extractField(lastTitleLine, "customTitle");
this.currentSessionTitle = title || undefined;
}
On abnormal exit, this shutdown path never runs → stat-log index has no customTitle → claude -r mytest returns nothing.
Fix
Either:
- Write to stat-log index immediately on
/rename, not just on shutdown - Fall back to scanning JSONL when stat-log lookup fails — the
custom-titleentry is already there - Rebuild the index on startup if it's stale (detect by comparing JSONL mtime vs index mtime)
Related
- #24065 — Same bug, reported 2026-02-08, closed as stale without fix
- #37437 — Same architectural pattern: data exists in JSONL but index/chain walker can't reach it
Environment
- Claude Code 2.1.81
- OS: Arch Linux
- Terminal: Ghostty
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗