Resume / turn-end writes duplicate last-prompt and ai-title entries, causing duplicate session entries in the picker and duplicate first-message bubbles

Resolved 💬 2 comments Opened May 24, 2026 by quanru Closed Jun 25, 2026

Summary

After resuming a session (claude --resume <id>), the session picker briefly shows two identical entries that later collapse into one, and any subsequent session has its first user message rendered twice in the bubble list. The underlying cause is that Claude Code writes multiple last-prompt and ai-title records to the transcript jsonl for a single user turn.

Reproduction

  1. Start a session, send one prompt, exit.
  2. claude --resume <session-id> --dangerously-skip-permissions
  3. Send one prompt, wait for the assistant turn to finish, exit.
  4. Open ~/.claude/projects/<encoded-cwd>/<session-id>.jsonl and grep:

``
jq -c 'select(.type=="last-prompt" or .type=="ai-title")' <file>
``

Observed jsonl pattern (real sample, redacted)

For a single user turn, the transcript contains:

{"type":"last-prompt","lastPrompt":"<same text>","leafUuid":"AAAA...","sessionId":"S"}
{"type":"ai-title","aiTitle":"<same title>","sessionId":"S"}
{"type":"last-prompt","lastPrompt":"<same text>","leafUuid":"BBBB...","sessionId":"S"}   <- duplicate
{"type":"ai-title","aiTitle":"<same title>","sessionId":"S"}                              <- duplicate
{"type":"ai-title","aiTitle":"<same title>","sessionId":"S"}                              <- duplicate

The two last-prompt entries carry the same lastPrompt string but different leafUuids, written within a few seconds of each other for the same single user input. ai-title is written 2-3x per turn with identical content.

Aggregated counts from one affected session:

| metric | value |
|------------------------------|-------|
| total \last-prompt\ records | 15 |
| unique \leafUuid\ values | 14 |
| unique \lastPrompt\ strings | 8 |

i.e. some prompts have up to 6 \last-prompt\ records pointing at them.

Only one actual \type:\"user\"\ message exists per turn, so the user input itself is not double-written - only the metadata is.

Impact on UI

  • Session picker / checkpoint selector: each \last-prompt\ is rendered as a separate restorable leaf, so the same session shows up N times with identical titles. The list eventually self-heals to one entry (presumably by a dedupe pass), but the flicker is visible on every resume.
  • Bubble list of the next session: the first user message is shown twice because two \last-prompt\ records exist for it.

Environment

  • macOS 25.1.0 (Darwin)
  • Claude Code (CLI), reproduced repeatedly across \--resume\ invocations
  • Project dir: \~/.claude/projects/-Volumes-...\

Suggested fix

\last-prompt\ and \ai-title\ writes appear to be triggered more than once at turn-end / resume. De-duplicating at write time (or persisting only the final state per turn) would fix both UI symptoms with no migration needed for existing transcripts.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗