[BUG] Desktop restart-continuation copies the full transcript into a new session file, and strands the old one (unbounded duplication when `cleanupPeriodDays` is raised)

Status Open
Reported on v2.1.245
Maintainer reply None cached
Activity 0 comments · opened Aug 25, 2026

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?

When the Desktop app restarts and the user continues an existing conversation, the app does not reopen the old transcript.
Instead it starts a new CLI session id and writes a full copy of the conversation history into a new file under %USERPROFILE%\.claude\projects\<project-slug>\.
The old transcript stays on disk, unreferenced.

The copy is re-stamped.
The earliest timestamp in the new file is the moment of the copy, not the conversation's original start.

This repeats on every restart.
Each cycle strands one more full copy of the conversation.
The app's registry entry (%APPDATA%\Claude\claude-code-sessions\...\local_*.json) updates its cliSessionId to the newest id.
Only the newest file is referenced.
The older copies become invisible to the UI.

How I found this: I was auditing my ~/.claude/projects folder because it had grown to about 500 MB.
Most of it turned out to be files the app no longer shows.
Cross-checking those files against the app's session registry showed that 23 of 79 invisible transcripts were earlier copies of just 5 conversations I still use.
One conversation had 8 stranded copies.
A single day-long conversation had already left 2.

These copies are apparently left for the retention sweep (cleanupPeriodDays, default 30 days) to collect.
Users who raise that setting to keep long-lived sessions accumulate the copies forever.
Nothing else removes them, and no UI shows them.

What Should Happen?

Any of these would resolve it:

  • Continuing after a restart appends to the existing transcript instead of copying it.
  • The superseded file is removed (or shown somewhere) once the new copy is written.
  • The behavior is documented, so users with long retention know that a long-lived conversation can hold N full plaintext copies on disk.

Error Messages/Logs

Steps to Reproduce

  1. In the Desktop app (Code tab), start a session in any project and exchange a few messages.
  2. Note its transcript file: %USERPROFILE%\.claude\projects\<project-slug>\<session-id>.jsonl
  3. Fully quit the app (including the tray icon) and reopen it.
  4. Open the same conversation and send one message.
  5. Look at the project folder again.

A new <new-id>.jsonl exists with the full prior history and re-stamped timestamps.
The registry entry now points at the new id.
The old file is still there, unreferenced.

  1. Repeat steps 3 to 5.

Each cycle strands one more copy.

Claude Model

None

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.245 (Claude Code)

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

Other

Additional Information

Impact

This is not an exploit and I am not claiming one, but it is a real privacy concern.
It is a data lifecycle problem with two real costs:

  • Privacy: every stranded copy is a complete plaintext transcript.

That includes tool results and any file contents or command output that passed through the conversation.
The user has no way to know these copies exist.

  • Disk: duplication is unbounded for long-lived conversations.

Each copy is the full transcript, so a conversation restarted N times costs roughly N times its size.

Related issues (not duplicates)

Same family of "file left behind for the retention sweep", but different mechanisms:

  • #89547 (GUI delete removes only the registry entry)
  • #59736 and #81907 (registry entries lost while transcripts remain).

This report is specifically about restart-continuation creating the copies.

View original on GitHub ↗