[BUG] Claude Code transcripts loss

Resolved 💬 3 comments Opened Apr 17, 2026 by ukeich Closed May 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?

Claude Code: CLI transcripts silently disappear from ~/.claude/projects/, and sidebar stubs self-destruct on click

Related but distinct: #29373, #29154, #29172 are all about update-triggered sidebar loss. This report is about an ongoing, post-update failure mode (the jsonls keep disappearing) plus a separate stub-corruption step not covered in those issues.

Environment

  • macOS: 26.4 (25E246)
  • Claude Desktop: 1.3109.0
  • Claude Code CLI bundled: 2.1.111
  • Setup: two Claude accounts used on the same Mac, signed in/out frequently to switch between work contexts. Not confirmed this is required to trigger the bug, just describing my setup.

Summary

Two interacting bugs cause silent loss of historical Claude Code sessions:

  1. Main <sessionId>.jsonl transcripts under ~/.claude/projects/<encoded-cwd>/ disappear over time. I don't know the exact trigger — only the correlates described below.
  2. When the user clicks a sidebar thread whose transcript is missing, the app wipes the stub's cliSessionId on disk, making manual recovery (e.g. from Time Machine) much harder.

Bug 1 — Transcripts disappear from ~/.claude/projects/

~/.claude/projects/<encoded-cwd>/<sessionId>.jsonl files are missing for many older threads, even though the sidebar stubs (~/Library/Application Support/Claude/claude-code-sessions/<org>/<workspace>/local_*.json) for those threads still exist. Clicking such a stub shows "No messages yet".

Oddly, the subagent traces under ~/.claude/projects/<encoded-cwd>/<sessionId>/subagents/ are left intact — only the main <sessionId>.jsonl and its enclosing per-session directory are gone. So you end up with orphaned subagents/ dirs next to the index, with no main transcript.

What I can say about the trigger: I don't know for sure. The Claude.ai desktop log (~/Library/Logs/Claude/main.log) records 155 [growthbook] refreshing for account change events between the last real activity of one of my lost threads (2026-03-17) and the first Transcript … no longer exists, starting fresh log line for it (2026-04-15). That's highly suggestive, but also a period over which the app was quit/relaunched and updated many times, so account switching is only one of several possible culprits. A re-loss I observed today happened about 10 minutes after an app quit, with no account change in between — so quit/restart cycles alone seem sufficient to reproduce at least some of the reaping.

Bug 2 — Stub self-destructs on click when transcript is missing

When a user clicks a sidebar thread whose transcript was reaped, the log shows:

[CCD] Transcript for <sessionId> no longer exists, starting fresh

The app then wipes the stub's cliSessionId field on disk so it can "start fresh". Even if the transcript file is then restored manually, the stub no longer points to it, and the sidebar still shows "No messages yet". Worse, the wiped state is cached in memory, so subsequent focus events re-write the wiped stub back to disk — clobbering any manual repair until the app is quit and relaunched.

Reproduction

Bug 1 (transcript disappearance — partial, not fully controlled)

I don't have a deterministic repro. What I can say:

  1. After extended normal use of Claude Desktop + Claude Code over weeks/months (with frequent quits, relaunches, desktop updates, and account switches), many older <sessionId>.jsonl files under ~/.claude/projects/ are gone while their sidebar stubs remain.
  2. Today I recovered two such jsonls from Time Machine and copied them back into the project directory. They were reaped again within a couple of hours — about 10 minutes after an app quit/relaunch, with no account change in between.

Bug 2 (stub self-destructs on click — fully reproducible, seen live today)

  1. Arrange for a broken stub: sidebar entry exists, but its cliSessionId points to a missing .jsonl under ~/.claude/projects/<encoded-cwd>/.
  2. Click the entry in the sidebar.
  3. Observe in ~/Library/Logs/Claude/main.log:

``
[CCD] Transcript for <sessionId> no longer exists, starting fresh
``

  1. Observe in the stub file on disk: cliSessionId is now null.
  2. Manually rewrite the stub to restore cliSessionId. Click the entry again without quitting the app. The app re-saves the stub with cliSessionId: null, clobbering the fix (in-memory cached state overwriting disk). Only quitting and relaunching the app breaks that cycle.

This is reproducible on demand — I reproduced it multiple times today while testing a recovery script.

Impact

  • Users lose CLI transcripts silently. No warning, no recovery UI.
  • Sidebar entries remain, so the loss isn't visible until a thread is clicked.
  • Manual recovery (e.g. from Time Machine) is possible but fragile: the reaping recurs, and Bug 2 makes each recovery attempt harder than it needs to be.

Suggested fixes

  1. Whatever is pruning ~/.claude/projects/ during quit/restart/account-change, stop pruning transcripts that still have a valid sidebar stub referring to them. At the very least, never remove a <sessionId>.jsonl when a stub anywhere on the machine has a matching cliSessionId.
  2. When "Transcript no longer exists, starting fresh" fires, do not wipe cliSessionId. If the user chooses to continue the session, a fresh sessionId gets created anyway. Wiping the existing one makes Time-Machine-style recovery much harder.
  3. Surface a warning ("Transcript for this thread wasn't found — start fresh, or cancel to investigate?") rather than silently mutating state.
  4. Bonus: a "where did my history go?" diagnostic / recovery tool. Given how many overlapping closed issues there are about sidebar-vs-disk mismatches (#29373, #29154, #29172), a built-in "rescan ~/.claude/projects/ and rebuild sidebar stubs" command would save users a lot of manual forensics.

Workaround I've been using

I wrote a small Python script that:

  • reads ~/Library/Application Support/Claude/claude-code-sessions/<org>/<workspace>/local_*.json stubs,
  • finds broken ones (no cliSessionId, or pointing to a missing jsonl),
  • matches them against recovered jsonls (from Time Machine) by sessionId or by cwd+firstPrompt,
  • copies jsonls into ~/.claude/projects/<encoded-cwd>/,
  • writes a fresh sessions-index.json,
  • patches the stub to restore cliSessionId.

Happy to share if helpful for building a first-party recovery tool.

What Should Happen?

Transcripts shouldn't get lost...

Error Messages/Logs

Steps to Reproduce

See above

Claude Model

Opus

Is this a regression?

No, this never worked

Last Working Version

_No response_

Claude Code Version

2.1.111 (CLI) 1.3109.0 (Desktop)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗

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