VS Code extension: 30-day retention cleanup silently deletes content of sessions whose tabs are still open, then shows generic 'No conversation found'
Environment
- Claude Code version: 2.1.215
- Interface: VS Code native extension (
claude-vscodeentrypoint) - OS: macOS
cleanupPeriodDays: not set (default, 30 days)
Summary
A session tab that had been open continuously in the VS Code sidebar for about a month stopped working. Renaming it in the sidebar, then trying to open it, produced:
Error: Claude Code returned an error result: No conversation found with session ID: <session-id>
Root cause (as best I can reconstruct it)
The session was created roughly a month ago and had a real conversation in it. The tab was left open in VS Code the whole time, without that UI session ever restarting. At some point during that month, a routine Claude Code startup triggered the default retention cleanup (cleanupPeriodDays, 30 days by default, not overridden in this case) and removed the underlying transcript file from ~/.claude/projects/<project-slug>/<session-id>.jsonl, since it had aged past the retention window.
Because the sidebar tab was never closed/reloaded, the UI kept showing the session (title, and in one case a cached last-prompt preview) as if it were still there. Interacting with it today (renaming it) caused a brand-new file to be written for that session ID — but containing only lightweight bookkeeping, no conversation:
{"type":"ai-title","aiTitle":"Read initial session files","sessionId":"<session-id>"}
{"type":"mode","mode":"normal","sessionId":"<session-id>"}
Both lines have identical created/modified timestamps (today), confirming this file was freshly written today, not the original month-old transcript. The real conversation is gone — deleted by retention cleanup while the tab was still open and appeared usable.
A second tab from the same period showed the same signature. It retains a fuller picture — presumably cached in the extension's own UI-side state rather than the (now-deleted) transcript — including rename history and a last-prompt preview of a real prompt that had been sent:
{"type":"custom-title","sessionId":"<id2>","customTitle":"Milestone Audit"}
{"type":"custom-title","sessionId":"<id2>","customTitle":"Milestone Audit 1"}
{"type":"last-prompt","lastPrompt":"now, analyse the user experience and provide your complete analysis, feedback and recommendations for frog leap improvement possibilities in the user interface and screen flows. this would be part a c…","leafUuid":"<leaf-uuid>","sessionId":"<id2>"}
{"type":"custom-title","customTitle":"Milestone Audit 1","sessionId":"<id2>"}
{"type":"ai-title","aiTitle":"Review initial project context and files","sessionId":"<id2>"}
But — critically — the leafUuid referenced here does not exist as an actual message node ("uuid":"<leaf-uuid>") in any .jsonl file anywhere under ~/.claude/projects/ on this machine. There is only one project directory on the machine, ruling out the content having landed under a different, unlabeled session ID elsewhere. The response that prompt generated is simply gone.
What this is not
This does not look like a live message-persistence failure (my first theory, since corrected) — the timestamps and metadata pattern only make sense once you know the sessions were created a month prior and the tabs stayed open the whole time. It's retention cleanup doing exactly what it's configured to do, but doing it silently to sessions a user still has open and considers active.
Expected behavior
- A session whose tab is still open in the VS Code sidebar shouldn't be silently eligible for retention cleanup — or at minimum, the user should be warned before it happens.
- If a session's content has already been removed by retention when the user goes to open it, the error should say so plainly (e.g. "This conversation's content passed your 30-day retention window and was removed") rather than the generic "No conversation found," which reads as a bug rather than expected, configured behavior.
- Consider not regenerating a same-ID stub file with fresh timestamps on interaction with an already-cleaned-up session — it currently masks when the content was actually lost and makes the failure look like a fresh, live persistence bug rather than a retention-driven one.
Impact
Silent, unrecoverable loss of a real conversation with no warning at any point — the tab looked normal and open right up until the moment it was used, then failed with an error message that gives no indication retention/expiry was the cause.