[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
- In
.zprofileexport environment variable likeexport INCIDENT_IO_READONLY="..." - Reference said environment variable in skill like $HOME/.claude/skills/incident-detective/SKILL.md (likely not required but case here)
- 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)This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗