CLAUDE_ENV_FILE written but not sourced for Bash tool calls on Windows
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
On Windows, CLAUDE_ENV_FILE is correctly provided to SessionStart hooks and the env file is written with valid export statements. However, subsequent Bash tool calls do not have access to the exported environment variables — the file is never sourced.
This differs from #15840 (env file not provided) and #14433 (not sourced after /clear). Here, the file IS provided and written on initial session start, but never sourced for any Bash tool call.
Reproduction Steps
- Create a
SessionStarthook that writes toCLAUDE_ENV_FILE:
{
"hooks": {
"SessionStart": [{
"hooks": [{
"type": "command",
"command": "node -e \"const fs=require('fs'); if(process.env.CLAUDE_ENV_FILE) fs.appendFileSync(process.env.CLAUDE_ENV_FILE, 'export MY_TEST_VAR=hello\n');\""
}]
}]
}
}
- Start a new Claude Code session on Windows
- Ask Claude to run:
echo $MY_TEST_VAR - Result: empty. The variable is not set.
Diagnostic Evidence
Added debug logging to the SessionStart hook to write process.env.CLAUDE_ENV_FILE to a file:
CLAUDE_ENV_FILE=C:\Users\<user>\.claude\session-env\<session-id>\sessionstart-hook-1.sh
Contents of sessionstart-hook-1.sh (correctly written):
export WIZ_SCRIPTS="C:/Users/<user>/.claude/plugins/cache/lansweeper-tools/wiz/3.7.0/scripts"
export TMPDIR="/tmp/claude"
export CLAUDE_CODE_DISABLE_1M_CONTEXT=1
Bash tool call results:
WIZ_SCRIPTS= (empty)
TMPDIR=/tmp (should be /tmp/claude)
CLAUDE_ENV_FILE= (empty)
None of the exported variables are available. The file exists, has correct content, but is not sourced.
Expected Behavior
Per the hooks documentation: "Claude Code will source this file before each Bash command, making the environment persistent across all commands."
Environment variables written to CLAUDE_ENV_FILE during SessionStart should be available in subsequent Bash tool calls on Windows.
Environment
- Claude Code version: 2.1.33
- OS: Windows 11 Enterprise 10.0.26200
- Shell: Git Bash (via Claude Code's default Windows shell)
- Node.js: v22.20.0
Related Issues
- #15840 —
CLAUDE_ENV_FILEnot provided to hooks (macOS) — different: on Windows it IS provided - #14433 — not sourced after
/clear(macOS) — different: on Windows it's not sourced at all, not just after/clear - #24775 — session ID mismatch on resume — potentially related if the sourcing logic has a path resolution issue on Windows
7 Comments
Found 2 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
Additional evidence: debug log shows no env file sourcing
Ran CC with debug logging on Windows. The SessionStart hook runs and writes to
CLAUDE_ENV_FILEsuccessfully, but there is no debug log entry showing CC sourcing the resulting.shfile.Relevant excerpts from the debug log:
The hook completes successfully (writes
export WIZ_SCRIPTS=...to the env file), but there is no subsequent log line about sourcing the env file. On macOS/Linux there should be a sourcing step between hook completion and the first Bash tool call — on Windows this step appears to be missing entirely.Subsequent Bash tool calls confirm none of the exported variables are available:
Impact: plugin ecosystem broken on Windows
This bug completely breaks the plugin backtick command (
!) mechanism on Windows. Any plugin that usesCLAUDE_ENV_FILEto export path variables for dynamic context in command/skill.mdfiles is dead on arrival.Concrete example: Our marketplace plugin (wiz) exports
WIZ_SCRIPTSpointing to the plugin's scripts directory. Commands like/wiz:reviewuse backtick commands:On macOS/Linux this works because
CLAUDE_ENV_FILEis sourced. On Windows:$WIZ_SCRIPTSis empty or stale in backtick commands ❌!block that references the variable crashes withMODULE_NOT_FOUND❌Workaround attempted: We set
WIZ_SCRIPTSas a persistent Windows user env var via PowerShell[Environment]::SetEnvironmentVariable(...). This only works after a full CC restart AND a new shell inheriting the updated env — it doesn't help the current session, and breaks on version upgrades (old path persists until restart).Scale: This affects every backtick command across 26 commands and 18 skills in our plugin. There is no clean workaround — the plugin marketplace on Windows is fundamentally broken without env file sourcing.
Would love to see this prioritized. Happy to help test a fix.
CLAUDE_ENV_FILE not sourced on Windows — root cause analysis
---
Root cause identified: This is not a sourcing bug - it's an intentional skip. The session env loader function (
cn7in the compiled bundle) contains an early return:The entire
CLAUDE_ENV_FILEmechanism is disabled on Windows by design. The hook runs, the file gets created with valid content, but CC never attempts to source it.Why the guard is unnecessary for Git Bash users:
CC on Windows defaults to Git Bash (
CLAUDE_CODE_GIT_BASH_PATHis set in env). Git Bash is a POSIX shell -source $fileworks identically to Linux/Mac. The env files are already written with valid bash syntax (KEY=VALUE). There's nothing Windows-specific about sourcing them in Git Bash.I verified this manually:
source ~/.claude/session-env/<session-id>/sessionstart-hook-0.shin a CC Bash tool call correctly loads all variables. The file format is fine, the shell can handle it - CC just refuses to try.Proposed fix (minimal):
For Git Bash (the default shell on Windows), remove the early return - the existing Linux/Mac sourcing logic should work as-is since it's the same shell. If CC detects PowerShell or cmd.exe as the shell, the guard can remain until a per-shell adapter is implemented.
This would unblock the entire Windows plugin ecosystem without risking PowerShell/cmd edge cases.
This issue was fixed as of version 2.1.111.
@claude this is still broken in v2.1.117, I fixed it by adding a custom global hook.
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.