Bug: --setting-sources local causes cleanup to ignore cleanupPeriodDays, silently deleting conversations globally

Resolved 💬 2 comments Opened Apr 9, 2026 by Butanium Closed Apr 9, 2026

Summary

claude -p --setting-sources local starts background housekeeping that ignores the user's cleanupPeriodDays setting in ~/.claude/settings.json, falling back to the 30-day default. This silently deletes conversation .jsonl files across all projects, not just the current one.

Impact

I lost months of conversation history across dozens of projects. I had cleanupPeriodDays: 1200 set in ~/.claude/settings.json since February 25, but batch claude -p --setting-sources local judging runs triggered cleanup with the 30-day default, wiping all conversations older than ~30 days globally.

The session subdirectories (subagent transcripts, tool-results) survived — only the main .jsonl files were deleted, leaving orphaned directories everywhere.

Root Cause

Traced through decompiled v2.1.63 source (the version running when data loss occurred):

  1. --setting-sources local excludes userSettings: getEnabledSettingSources() returns ["localSettings", "policySettings", "flagSettings"]userSettings is not included
  2. loadSettingsFromDisk() skips ~/.claude/settings.json: Since userSettings is not in the enabled list, the file is never read. The merged settings have no cleanupPeriodDays
  3. Cleanup falls back to 30 days: getCutoffDate() uses settings.cleanupPeriodDays ?? 30
  4. The safety guard is also defeated: rawSettingsContainsKey("cleanupPeriodDays") only checks enabled sources, so it doesn't find the key in userSettings → guard doesn't trigger
  5. claude -p runs background housekeeping: startBackgroundHousekeeping() is called in the non-interactive path, with cleanup firing 10 minutes after session start
  6. --no-session-persistence doesn't help: It only prevents writing new transcripts, it does NOT disable cleanup
  7. Cleanup is global: cleanupOldSessionFiles() walks ~/.claude/projects/ and deletes across ALL projects

Reproduction

# Set a long retention
echo '{"cleanupPeriodDays": 9999}' > ~/.claude/settings.json

# This will ignore the 9999 and use 30:
echo "test" | claude -p --setting-sources local --no-session-persistence --model haiku
# If session lives 10+ minutes, cleanup runs with 30-day default

Suggested Fixes

Any of these would prevent the issue:

  1. Always read cleanupPeriodDays from user settings for cleanup, regardless of --setting-sources — cleanup is a global operation and should respect global config
  2. Disable background housekeeping in piped mode (claude -p) — short-lived batch processes shouldn't run global cleanup
  3. Make rawSettingsContainsKey check all settings files, not just enabled sources
  4. Scope cleanup to the current project instead of walking all of ~/.claude/projects/

Environment

  • Claude Code v2.1.63 (when data loss occurred), currently on v2.1.89
  • Linux (cluster)
  • Bug confirmed via decompiled v2.1.63 source code analysis

🤖 Generated with Claude Code

View original on GitHub ↗

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