[BUG] Claude Code isn't picking up environment variables correctly

Resolved 💬 3 comments Opened Mar 9, 2026 by thnk2wn Closed Mar 9, 2026

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?

In my .zprofile I have: export INCIDENT_IO_READONLY="..."

But claude code can't seem to expand. Cursor picks it up fine and it's been set in my environment for many weeks. It can seem to do printenv but then it results in prompting me each time.

⏺ Let me diagnose why the env var isn't visible.

⏺ Bash(echo "INCIDENT_IO_READONLY length: ${#INCIDENT_IO_READONLY}"; echo "---"; env | grep -i incident || echo "Not in env"; echo "---"; grep -c INCIDENT_IO_READONLY…)
  ⎿  INCIDENT_IO_READONLY length:
     ---
     INCIDENT_IO_READONLY=redacted
     … +5 lines (ctrl+o to expand)

⏺ Interesting — it's in env output but the shell expansion is empty. Let me check further.

⏺ Bash(printenv INCIDENT_IO_READONLY)
  ⎿  redacted

⏺ Bash(curl -s -H "Authorization: Bearer $(printenv INCIDENT_IO_READONLY)" "https://api.incident.io/v2/incidents/838" | jq '.incident | {name, reference, summary: .sum…)
  ⎿  {
       "name": "my-app job failed with exit code 2 (Error) and backoff limit exceeded",
       "reference": "INC-838",
     … +6 lines (ctrl+o to expand)

⏺ The env var is in the process environment but not being expanded as a shell variable by zsh. printenv works. Now let me get the full incident details and linked alerts.

⏺ Bash(export INCIDENT_IO_READONLY=$(printenv INCIDENT_IO_READONLY) && curl -s -H "Authorization: Bearer $INCIDENT_IO_READONLY" "https://api.incident.io/v2/incidents/8…)
  ⎿  Running…

⏺ Bash(export INCIDENT_IO_READONLY=$(printenv INCIDENT_IO_READONLY) && curl -s -H "Authorization: Bearer $INCIDENT_IO_READONLY" "https://api.incident.io/v2/incidents/8…)
  ⎿  Waiting…

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 Bash command

   export INCIDENT_IO_READONLY=$(printenv INCIDENT_IO_READONLY) && curl -s -H "Authorization: Bearer $INCIDENT_IO_READONLY" "https://api.incident.io/v2/incidents/838" | jq '.incident.summary'
   Fetch full incident summary

 Command contains $() command substitution

 Do you want to proceed?
 ❯ 1. Yes
   2. No

 Esc to cancel · Tab to amend · ctrl+e to explain

Later run indicated:

 Bash(source ~/.zprofile 2>/dev/null; echo "length: ${#INCIDENT_IO_READONLY}")
  ⎿  length: 68

⏺ The variable isn't automatically available as a shell variable in the Bash tool's context — it's in the process environment but zsh doesn't promote inherited env vars to shell variables by default. Sourcing ~/.zprofile fixes it.

What Should Happen?

It should recognize environment variables sourced in my profile like this, especially ones I'm pointing out in a SKILL.md it's using. Haven't noticed this behavior with Cursor, codex, opencode etc.

Error Messages/Logs

Steps to Reproduce

  1. In .zprofile export environment variable like export INCIDENT_IO_READONLY="..."
  2. Reference said environment variable in skill like $HOME/.claude/skills/incident-detective/SKILL.md (likely not required but case here)
  3. Trigger skill being used to reference environment variable

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.71

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Other

Additional Information

Using Ghostty on masOC Tahoe Version 26.4 Beta (25E5223i).

I am starting claude code with alias claude="CHOKIDAR_USEPOLLING=1 claude" due to startup issues:

This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason:
Error: EOPNOTSUPP: unknown error, watch '/var/folders/10/chc1sb1j67n_rk72k9xkndxw0000gn/T/vscd-session-aeb4a7cc99.sock'
    at watch (unknown)
    at new FSWatcher (node:fs:29:31)
    at watch (node:fs:296:23)
    at AC_ (/$bunfs/root/claude:392:6265)
    at PMD (/$bunfs/root/claude:392:11479)
    at _watchWithNodeFs (/$bunfs/root/claude:392:6746)
    at _handleFile (/$bunfs/root/claude:392:7489)
    at _addToNodeFs (/$bunfs/root/claude:392:10516)
    at processTicksAndRejections (native:7:39)

View original on GitHub ↗

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