[BUG] Session .jsonl files pruned to 1-per-project despite cleanupPeriodDays: 9999 — correlates with autoUploadSessions: true

Status Fixed / completed
Reported on v2.1.146
Maintainer reply None cached
Activity 1 comment · opened Aug 15, 2026 · closed Aug 17, 2026

Environment

  • Version: 2.1.146 (installed via npm at ~/.nvm/versions/node/v24.13.1/lib/node_modules/@anthropic-ai/claude-code)
  • Platform: Linux (Fedora 44, kernel 7.1.7)
  • Filesystem: btrfs
  • Install: npm global, no VS Code / Desktop app in play

Settings (~/.claude/settings.json, relevant keys)

{
  "cleanupPeriodDays": 9999,
  "autoUploadSessions": true,
  "model": "opus"
}

settings.json is valid JSON and validates cleanly. settings.local.json only contains a permissions.allow array.

Symptom

Session transcripts (~/.claude/projects/<slug>/*.jsonl) are being silently deleted despite cleanupPeriodDays: 9999. Deletion pattern is not age-based — it prunes to exactly 1 jsonl file per affected project, keeping only the most recent (active) session.

Evidence

.last-cleanup marker fires on schedule: ~/.claude/.last-cleanup = 2026-08-15T16:27:20.874Z.

Per-project jsonl counts (dir birthdates in first column):

2026-03-03  files=0  -home-oche-COI-AWS
2026-03-13  files=1  -home-oche-Ocheverse-ng-1
2026-03-29  files=14 -home-oche             ← preserved
2026-04-02  files=1  -home-oche-personal-stuff-Diagram
2026-04-03  files=5  -home-oche-cumulus-stuff
2026-04-12  files=7  -home-oche-metcoredigitech
2026-05-16  files=1  -home-oche-fusionintel-foodease-ai
2026-05-16  files=1  -home-oche-personal-stuff-cifra
2026-06-30  files=2  -home-oche-fusionintel
2026-07-01  files=1  -home-oche-personal-stuff-aws-calculator
2026-07-06  files=1  -home-oche-personal-stuff-Infra-Monitor

Six projects are reduced to exactly 1 file. But -home-oche has jsonls dating to 2026-03-29 (5+ months old) — so cleanupPeriodDays: 9999 is being respected for age-based retention. Some other code path is doing the per-project prune.

Proof that sessions existed and were deleted

~/.claude/history.jsonl still holds 61 user prompts for the cifra project across 2 sessionIds:

  • 18f0bae4-63a7-4d24-8ee1-990d6632a6bb (current session, jsonl exists)
  • cdcb6cbc-b0db-4c15-844b-e5b3b44b98d9 — 59 prompts from 2026-05-16 → 2026-06-05, jsonl gone

Sample recovered prompts:

[2026-05-16 12:38] let's start the backend
[2026-06-05 20:06] Abeg shut it down i wan sleep

Suspected culprit

strings on the compiled binary (.../claude-code/bin/claude.exe, Bun ELF) surfaces:

  • applyAutoUploadSessionsToAppState
  • autoUploadSessions (referenced 4+ times)
  • cleanupPeriodDays7 (default: 7)
  • Two guard strings that don't fire here:
  • Skipping retention cleanup: userSettings source is disabled (--setting-sources) ...
  • Skipping cleanup: settings have validation errors but cleanupPeriodDays was explicitly set.

Working hypothesis: when autoUploadSessions: true succeeds in uploading a session's transcript to the cloud, the local jsonl is pruned per project (keeping only the active one). Age-based retention still respects cleanupPeriodDays: 9999, but this second code path doesn't. This would explain why some projects (-home-oche) retain many files (perhaps uploads failed or were rate-limited) while others are trimmed to 1.

Impact

  • User-facing data loss with no warning, no trash, no log
  • cleanupPeriodDays: 9999 gives false confidence that transcripts are being kept
  • The .claude/projects/<slug>/memory/ subdirs and history.jsonl prompt records are preserved — asymmetry with the transcripts makes recovery partial

Related

  • #79758 — retention sweep has no warning/trash/log
  • #78821 — orchestrator jsonl deleted while subagents/ preserved (calls out "not retention")
  • #86730 — default cleanupPeriodDays silently deleted many transcripts (this issue is different: the setting is explicit, not default)

Ask

  1. Is autoUploadSessions supposed to trigger post-upload local prune? If so, please document and make it opt-in / gated by a separate setting.
  2. Any prune path outside cleanupPeriodDays should honor the same retention semantics or have its own clearly-named toggle.
  3. A dry-run or log line at prune time (prune: deleting <n> local jsonls for <project> after successful upload) would have made this diagnosable in seconds instead of hours.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗