claude-code - 💡(How to fix) Fix [FEATURE] CLAUDE_ENV_FILE should propagate to PowerShell tool and child plugins, not bash-only [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#60697Fetched 2026-05-20 03:51:51
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
0
Timeline (top)
labeled ×3commented ×1

Root Cause

  • Wrapper script for pwsh tools — works for the statusline (one entry point we control), but doesn't reach MCP servers, external plugins, or future tooling that Claude Code spawns directly. Wrapping isn't viable as a general answer.
  • Persist secrets to Windows User env via [Environment]::SetEnvironmentVariable($k, $v, 'User') — works mechanically but writes rotating 1Password tokens to the registry, persists past the session, and survives Claude Code exits. Security-smell.
  • Always launch Claude Code from a pre-populated shell (e.g. op run -- pwsh then claude) — works perfectly when remembered, but the SessionStart hook exists precisely because plain claude launches need to recover. Today the recovery is bash-only.

Fix Action

Fix / Workaround

  • Bash tool: JIRA_TOKEN, OCTOPUS_API_KEY, etc. all populated ✅
  • PowerShell tool: all $null
  • Statusline (pwsh, configured in .claude/settings.json): can't see the loaded vars, so it falsely shows 🔒 0/3 even though everything is loaded
  • Any pwsh-based plugin / MCP server: same — can't see them
  • 3rd-party plugins: not under our control, so no "just wrap it" workaround

We can patch our own statusline plugin to fall back to parsing ~/.claude/session-env/<sid>/sessionstart-hook-*.sh to recover a truthful indicator, but that's a band-aid for one consumer. The PowerShell tool, MCP servers, and external plugins remain blind. There is no user-land fix that covers all of them.

Workarounds considered and rejected

RAW_BUFFERClick to expand / collapse

What's the problem

CLAUDE_ENV_FILE (populated by SessionStart / Setup / CwdChanged / FileChanged hooks) is documented as making env vars "available in all subsequent Bash commands that Claude Code executes during the session" — and that's exactly what it does. The values land in bash tool subprocesses, but nothing else sees them.

On Windows with PowerShell as the daily driver, this creates a sharp split: bash tool calls have my OAuth / API tokens, while the PowerShell tool, the statusline command, MCP servers, and any external plugin Claude Code spawns directly all see $null for those same vars. Subagents have the same problem (already filed as #46696).

Why it matters

We use a SessionStart hook to resolve 1Password references in .claude/secrets.env via op inject and write the resulting export KEY='value' lines to $CLAUDE_ENV_FILE. This is exactly the workflow the docs describe.

Result today, on Windows + pwsh:

  • Bash tool: JIRA_TOKEN, OCTOPUS_API_KEY, etc. all populated ✅
  • PowerShell tool: all $null
  • Statusline (pwsh, configured in .claude/settings.json): can't see the loaded vars, so it falsely shows 🔒 0/3 even though everything is loaded
  • Any pwsh-based plugin / MCP server: same — can't see them
  • 3rd-party plugins: not under our control, so no "just wrap it" workaround

We can patch our own statusline plugin to fall back to parsing ~/.claude/session-env/<sid>/sessionstart-hook-*.sh to recover a truthful indicator, but that's a band-aid for one consumer. The PowerShell tool, MCP servers, and external plugins remain blind. There is no user-land fix that covers all of them.

What I'd like

Make CLAUDE_ENV_FILE semantics tool/shell-agnostic: when a hook appends KEY=value (or export KEY='value') lines to $CLAUDE_ENV_FILE, Claude Code should set those env vars on its own process so that every child process — bash tool, PowerShell tool, MCP servers, plugins, subagents, statusline command — inherits them naturally via OS-level env propagation.

That removes a whole class of "why doesn't X see my secrets" problems and also subsumes #46696 (subagent inheritance) and arguably #51862 (bash-tool sourcing), since with vars on the parent process there's no need to source anything per-child.

Acceptance suggestions

  • Parser accepts both KEY=value and export KEY='value' (the latter is what bash-style hook examples in your own docs produce).
  • Single-quote escaping ('\'') honored, since op inject output uses that.
  • $env:CLAUDE_ENV_FILE itself still set inside hook subprocesses so existing hooks continue to work unchanged.
  • Optional: surface the resolved env via /env (which would also close part of #41268).

Workarounds considered and rejected

  • Wrapper script for pwsh tools — works for the statusline (one entry point we control), but doesn't reach MCP servers, external plugins, or future tooling that Claude Code spawns directly. Wrapping isn't viable as a general answer.
  • Persist secrets to Windows User env via [Environment]::SetEnvironmentVariable($k, $v, 'User') — works mechanically but writes rotating 1Password tokens to the registry, persists past the session, and survives Claude Code exits. Security-smell.
  • Always launch Claude Code from a pre-populated shell (e.g. op run -- pwsh then claude) — works perfectly when remembered, but the SessionStart hook exists precisely because plain claude launches need to recover. Today the recovery is bash-only.

Environment

  • Claude Code: latest stable, Windows 11
  • Shell: PowerShell 7
  • Hook: SessionStart writing export KEY='value' lines to $CLAUDE_ENV_FILE (the exact format your hooks docs show)

Filed via Claude Code on my own behalf — meta enough that I had to flag it 😄

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix [FEATURE] CLAUDE_ENV_FILE should propagate to PowerShell tool and child plugins, not bash-only [1 comments, 2 participants]