Environment: Claude Code 2.1.280 (native install), Linux (Gentoo, kernel 6.18). CLAUDE_CONFIG_DIR set to a non-default directory; no ~/.claude existed before.
What happens
With CLAUDE_CONFIG_DIR=~/.config/claude, the daemon lock file is written to the configured directory, as expected, but the paths inside it point to the hardcoded default:
// ~/.config/claude/daemon.lock
{"pid":822296,"version":"2.1.280",
"jsonPath":"/home/<user>/.claude/daemon.json",
"logPath":"/home/<user>/.claude/daemon.log",
"origin":"transient","launchTarget":"/opt/bin/claude","processWrapper":"", ...}
So the process that honors CLAUDE_CONFIG_DIR for daemon.lock still resolves daemon.json / daemon.log under ~/.claude.
Probably related: after such sessions, ~/.claude/ and ~/.claude.json reappeared in $HOME. ~/.claude/projects/<slug>/<session-id>.jsonl contained only trailing session metadata records (last-prompt, ai-title, mode, permission-mode, cost-state, agent-name, no messages), while the full transcripts of the same session IDs were in $CLAUDE_CONFIG_DIR/projects/<slug>/. ~/.claude/backups/.claude.json.backup.* and ~/.claude.json (with projects for the same cwd's) were written at the same times. It looks like some end-of-session / daemon code path computes the config dir without CLAUDE_CONFIG_DIR.
Expected: everything that is placed under ~/.claude by default goes under $CLAUDE_CONFIG_DIR when it is set, including daemon files and session metadata.
Why it matters: besides XDG layouts (#1455), this breaks sandboxing setups that give Claude Code a dedicated config dir: files land outside of it, and parallel sandboxed instances would share ~/.claude/daemon.json.
Related, but different code paths: #79952 (config editing writes ~/.claude/settings.json), #1455.
(Written by Claude Code on the reporter's behalf.)
Environment: Claude Code 2.1.280 (native install), Linux (Gentoo, kernel 6.18).
CLAUDE_CONFIG_DIRset to a non-default directory; no~/.claudeexisted before.What happens
With
CLAUDE_CONFIG_DIR=~/.config/claude, the daemon lock file is written to the configured directory, as expected, but the paths inside it point to the hardcoded default:So the process that honors
CLAUDE_CONFIG_DIRfordaemon.lockstill resolvesdaemon.json/daemon.logunder~/.claude.Probably related: after such sessions,
~/.claude/and~/.claude.jsonreappeared in$HOME.~/.claude/projects/<slug>/<session-id>.jsonlcontained only trailing session metadata records (last-prompt,ai-title,mode,permission-mode,cost-state,agent-name, no messages), while the full transcripts of the same session IDs were in$CLAUDE_CONFIG_DIR/projects/<slug>/.~/.claude/backups/.claude.json.backup.*and~/.claude.json(withprojectsfor the same cwd's) were written at the same times. It looks like some end-of-session / daemon code path computes the config dir withoutCLAUDE_CONFIG_DIR.Expected: everything that is placed under
~/.claudeby default goes under$CLAUDE_CONFIG_DIRwhen it is set, including daemon files and session metadata.Why it matters: besides XDG layouts (#1455), this breaks sandboxing setups that give Claude Code a dedicated config dir: files land outside of it, and parallel sandboxed instances would share
~/.claude/daemon.json.Related, but different code paths: #79952 (config editing writes
~/.claude/settings.json), #1455.(Written by Claude Code on the reporter's behalf.)