CLAUDE_ENV_FILE: session ID mismatch on resume causes env files to be written to wrong directory
Description
This is a re-report of #24775, which was auto-closed as stale despite the bug still being present as of 2026-03-28.
When resuming a session (--continue, /resume, or context compaction), CLAUDE_ENV_FILE points to a startup session's directory, but the env file loading function reads from the resumed session's directory. This means environment variables written by SessionStart hooks are never found.
Steps to Reproduce
- Register a project SessionStart hook that writes to
CLAUDE_ENV_FILE:
``bash``
#!/bin/bash
INPUT=$(cat)
if [ -n "$CLAUDE_ENV_FILE" ]; then
echo 'export MY_TEST_VAR="hello"' >> "$CLAUDE_ENV_FILE"
fi
exit 0
- Start Claude Code interactively, then use
/resumeor--continueto resume the session
- In the resumed session, run:
````
echo $MY_TEST_VAR
- Expected:
hello - Actual: Variable is unset
Root Cause
At hook execution time (SessionStart), the env file path is generated using the startup session ID (a transient session created before the resume completes):
~/.config/claude/session-env/STARTUP_SESSION_ID/sessionstart-hook-N.sh
At Bash tool execution time, the env loader reads from the resumed session ID:
~/.config/claude/session-env/RESUMED_SESSION_ID/
Since these are different directories, the env files are never found.
Evidence
Debug hooks logging CLAUDE_ENV_FILE and stdin JSON during SessionStart:
# Startup SessionStart (source: "startup")
CLAUDE_ENV_FILE=~/.config/claude/session-env/21a1c086-.../sessionstart-hook-0.sh
stdin: {"session_id":"21a1c086-...","source":"startup"}
# Resume SessionStart (source: "resume")
CLAUDE_ENV_FILE=~/.config/claude/session-env/21a1c086-.../sessionstart-hook-0.sh ← SAME startup dir
stdin: {"session_id":"8b55bdb2-...","source":"resume"} ← DIFFERENT session ID
Then in Bash tool calls, the env loader looks in session-env/8b55bdb2-.../ which is empty.
Confirmed working on fresh sessions: Pre-seeding session-env/SESSION_ID/sessionstart-hook-0.sh and running claude --session-id SESSION_ID correctly sources the env file. The loading mechanism works — only the session ID mismatch on resume is broken.
Confirmed broken on resume: Writing to the startup session's directory (where hooks actually write) and verifying the resumed session can't find those files.
Additional Note
There is also a caching issue: the env loader caches its result after the first call. If the first call happens before env files exist, it caches null and never re-checks. The cache is only invalidated on compaction/SessionStart events. This is a secondary concern but compounds the primary session ID mismatch.
Environment
- Claude Code 2.1.x (confirmed still present as of 2026-03-28)
- Linux (WSL2)
- Hooks registered in
.claude/settings.json(project level)
Related Issues
- #24775 — Original report (auto-closed as stale by bot)
- #15840 — CLAUDE_ENV_FILE empty string (different bug)
- #11649 — CLAUDE_ENV_FILE not passed to plugin hooks (fixed)
- #12418 — CLAUDE_ENV_FILE not sourced on resume (closed as duplicate of #11649, but this is a separate root cause)
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗