CLAUDE_ENV_FILE: session ID mismatch on resume causes env files to be written to wrong directory

Resolved 💬 4 comments Opened Mar 28, 2026 by cowwoc Closed May 27, 2026

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

  1. 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
``

  1. Start Claude Code interactively, then use /resume or --continue to resume the session
  1. In the resumed session, run:

``
echo $MY_TEST_VAR
``

  1. Expected: hello
  2. 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)

View original on GitHub ↗

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