[BUG] Claude loads my projects .env into its bash environment (!)

Resolved 💬 64 comments Opened Mar 8, 2025 by rasmuscnielsen Closed Apr 17, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

Environment

  • Platform (select one):
  • [x] Anthropic API
  • [ ] AWS Bedrock
  • [ ] Google Vertex AI
  • [ ] Other: <!-- specify -->
  • Claude CLI version: 0.2.35 (Claude Code)
  • Operating System: macOS 15.3.1
  • Terminal: Warp

Bug Description

For the life of me I couldn't figure out why Claude running my Laravel test suite was dropping my local development database every time. During testing, it should rather be using the test environment database for running migrations.

Then after a lot of digging I realized asking Claude to dump its env, it had loaded my projects .env file into its bash env. This causes Laravel to completely ignore whatever I have written in my .env file or any phpunit.xml.

Is it just me or does this seem like a massive issue? Big fan of Claude here and been using the CLI a ton. But I was under the impression that it was quite transparent in what It was doing, but somehow loading my .env wasn't on the list of things I was expecting 🤔

Steps to Reproduce

  1. Create an empty folder and create a .env file with the contents 'MY_SECRET_ENV=test'
  2. Open terminal, navigate to the folder and run claude
  3. Ask Claude to run env. Now you should see 'MY_SECRET_ENV=test ' listed in the output. This will not happen when you just type env in your own bash terminal.

Expected Behavior

Claude should not load my projects .env in its bash environment

Actual Behavior

See above.

View original on GitHub ↗

64 Comments

bcherny collaborator · 1 year ago

Hey! Yep Claude inherits your bash environment, so it can run commands on your behalf (with your approval). To do that, it sources your .zshrc/.bashrc, which will pull in env vars if your source them there. This is valuable for having Claude use AWS, GCP, various APIs, etc. on your behalf.

We'll update the docs to clarify this -- not good that it's surprising. Thanks for the feedback!

rasmuscnielsen · 1 year ago

Hey @bcherny

Thanks for your reply.

The problem here isn't that it inherits my bash/zsh environment. It's that it actually loads my projects .env file which isn't meant to run in the terminal environment, but strictly meant for the application to load.

It's seems unintuitive to me that Claude would just go and source that into the cli environment since this doesn't happen in the user's own terminal potentially causing different behavior running the exact same command.

bcherny collaborator · 1 year ago

cc @wolffiex for input

ericbuehl · 1 year ago

Noting that this still appears to be an issue as recent as v1.0.48

rsanheim · 11 months ago

This is still an issue as of 1.0.58 (native install) - I'm seeing claude code load .env.development files on startup. which means those env vars will then be in the current process context for things like test runs, scripts, etc, and basically make things very confusing for the agent and for developers.

It also means that if an env var is set in .env.development but not in .env.test (which most dotenv libraries will load for test, ie NODE_ENV=test or RAILS_ENV=test), the env vars in the process (loaded via claude code) will win when running tests.

By default dotenv libraries will assume the 'current environment' _wins_ over settings in .env files, so this means you may have something like DATABASE_URL set to something you don't want in when claude code runs something.

Reproduction:

> mkdir test-claude-env
> cd test-claude-env
> env | grep TEST_FOO # no output
> claude
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│                                                                                                                                                      │
│ Do you trust the files in this folder?                                                                                                               │
│                                                                                                                                                      │
│ /Users/rsanheim/test-claude-env                                                                                                                      │
│                                                                                                                                                      │
│ Claude Code may read files in this folder. Reading untrusted files may lead Claude Code to behave in unexpected ways.                                │
│                                                                                                                                                      │
│ With your permission Claude Code may execute files in this folder. Executing untrusted code is unsafe.                                               │
│                                                                                                                                                      │
│ https://docs.anthropic.com/s/claude-code-security                                                                                                    │
│                                                                                                                                                      │
│ ❯ 1. Yes, proceed                                                                                                                                    │
│   2. No, exit                                                                                                                                        │
│                                                                                                                                                      │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
   Enter to confirm · Esc to exit
╭───────────────────────────────────────────────────╮
│ ✻ Welcome to Claude Code!                         │
│                                                   │
│   /help for help, /status for your current setup  │
│                                                   │
│   cwd: /Users/rsanheim/test-claude-env            │
╰───────────────────────────────────────────────────╯

 Tips for getting started:

 1. Ask Claude to create a new app or clone a repository
 2. Use Claude to help with file analysis, editing, bash commands and git
 3. Be as specific as you would with another engineer for the best results
 4. ✔ Run /terminal-setup to set up terminal integration

 ※ Tip: Create custom slash commands by adding .md files to .claude/commands/ in your project or ~/.claude/commands/ for commands that work in any
 project

> do I have a TEST_FOO env var set in the current process?

⏺ I'll check if the TEST_FOO environment variable is set in the current process.

⏺ Bash(echo "${TEST_FOO:-not set}")
  ⎿  not set

⏺ No, TEST_FOO is not set.

> /exit
  ⎿  (no content)

╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ >                                                                                                                                                    │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
  -- INSERT --


> echo 'TEST_FOO=why' > .env.development
> cat .env.development
TEST_FOO=why
 > claude
╭───────────────────────────────────────────────────╮
│ ✻ Welcome to Claude Code!                         │
│                                                   │
│   /help for help, /status for your current setup  │
│                                                   │
│   cwd: /Users/rsanheim/test-claude-env            │
╰───────────────────────────────────────────────────╯

 Tips for getting started:

 1. Run /init to create a CLAUDE.md file with instructions for Claude
 2. Use Claude to help with file analysis, editing, bash commands and git
 3. Be as specific as you would with another engineer for the best results
 4. ✔ Run /terminal-setup to set up terminal integration

 ※ Tip: Use /theme to change the color theme

> do I have a TEST_FOO env var set in the current process?

⏺ I'll check if the TEST_FOO environment variable is set in the current process.

⏺ Bash(echo "${TEST_FOO:-not set}")
  ⎿  why

⏺ Yes, TEST_FOO is set to "why".

> /exit
  ⎿  (no content)

╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ >                                                                                                                                                    │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
  -- INSERT --

the real bad case, which can blow away local data, as the process env vars will win:

[~/test-claude-env] (6.437s) > cat .env.development
TEST_FOO=set-in-env-dev
[~/test-claude-env] (20ms) > echo TEST_FOO=set-in-env-test > .env.test
[~/test-claude-env] (19ms) > claude
╭───────────────────────────────────────────────────╮
│ ✻ Welcome to Claude Code!                         │
│                                                   │
│   /help for help, /status for your current setup  │
│                                                   │
│   cwd: /Users/rsanheim/test-claude-env            │
╰───────────────────────────────────────────────────╯

 Tips for getting started:

 1. Run /init to create a CLAUDE.md file with instructions for Claude
 2. Use Claude to help with file analysis, editing, bash commands and git
 3. Be as specific as you would with another engineer for the best results
 4. ✔ Run /terminal-setup to set up terminal integration

 ※ Tip: Ask Claude to create a todo list when working on complex tasks to track progress and remain on track

> what is the env var TEST_FOO set to?

⏺ I'll check the value of the TEST_FOO environment variable for you.

⏺ Bash(echo $TEST_FOO)
  ⎿  set-in-env-dev

⏺ The environment variable TEST_FOO is set to "set-in-env-dev".

╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ >                                                                                                                                                    │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
  -- INSERT --
rsanheim · 11 months ago

And just to verify, and to be super clear here, it isn't my own bash profile, or something that mise is doing or something. Here I spawn a new zsh shell, which I don't use daily and so the profile is basically empty:

>  /bin/zsh

rsanheim@studio ~ % cd test-claude-env
rsanheim@studio test-claude-env % env | grep TEST_FO
rsanheim@studio test-claude-env % cat .env.development
TEST_FOO=set-in-env-dev
rsanheim@studio test-claude-env % claude
╭───────────────────────────────────────────────────╮
│ ✻ Welcome to Claude Code!                         │
│                                                   │
│   /help for help, /status for your current setup  │
│                                                   │
│   cwd: /Users/rsanheim/test-claude-env            │
╰───────────────────────────────────────────────────╯

 Tips for getting started:

 1. Run /init to create a CLAUDE.md file with instructions for Claude
 2. Use Claude to help with file analysis, editing, bash commands and git
 3. Be as specific as you would with another engineer for the best results
 4. ✔ Run /terminal-setup to set up terminal integration

 ※ Tip: Hit shift+tab to cycle between default mode, auto-accept edit mode, and plan mode

> do i have a TEST_FOO env var set in the current environment?

⏺ I'll check if the TEST_FOO environment variable is set in your current environment.

⏺ Bash(echo "${TEST_FOO:-not set}")
  ⎿  set-in-env-dev

⏺ Yes, TEST_FOO is set to set-in-env-dev.
Dambre · 11 months ago

@rsanheim interestingly my claude code wasn't including this file before but it started doing this few days ago. I also have 1.0.58 version. claude.md instructions, settings.json, deny settings etc doesn't help. When I remove .env, I can use claude code normally again but that is not the way it should be.

wolffiex collaborator · 11 months ago

This is a bit of a mystery. I'm not able to reproduce on my system. @rsanheim can you redo your test with --debug and then look in the snapshot file for clues?

rasmuscnielsen · 11 months ago

Interestingly I've just tried to reproduce thebug since originally creating the issue, and now it doesn't seem to happen to me anymore (Claude Code 1.0.60). Back then it was consistent behavior.

Initially I assumed it was built into the tool that it always loaded the .env into the environment, but I wonder if it could be a bit more subtle since more people are experiencing the issue.

I'm not sure when the behavior changed for me, since I've not allowed Claude to execute my testsuite since I discovered this bug. And honestly not really sure if I still trust it to without having clear understanding of how this happened. in the first place 😄

@wolffiex Do you know if it was ever built into the tool that it would load the .env into the its environment? Or was this never explicit behavior?

Dambre · 11 months ago

@wolffiex adding my debug log

lukas ~/claude-test  $ env | grep TEST
lukas ~/claude-test  $ cat .env
TEST=test
lukas ~/claude-test  $ claude --debug
[DEBUG] Writing to temp file: /Users/lukas/.claude.json.tmp.43730.1753442341131
[DEBUG] Preserving file permissions: 100644
[DEBUG] Temp file written successfully, size: 2805369 bytes
[DEBUG] Applied original permissions to temp file
[DEBUG] Renaming /Users/lukas/.claude.json.tmp.43730.1753442341131 to /Users/lukas/.claude.json
[DEBUG] File /Users/lukas/.claude.json written atomically
[DEBUG] Creating shell snapshot for zsh (/bin/zsh)
[DEBUG] Creating snapshot at: /Users/lukas/.claude/shell-snapshots/snapshot-zsh-1753442341163-bdevej.sh
[DEBUG] Writing to temp file: /Users/lukas/.claude/todos/c0065a43-370f-496d-98c4-943554f781cb-agent-c0065a43-370f-496d-98c4-943554f781cb.json.tmp.43730.1753442341164
[DEBUG] Temp file written successfully, size: 2 bytes
[DEBUG] Renaming /Users/lukas/.claude/todos/c0065a43-370f-496d-98c4-943554f781cb-agent-c0065a43-370f-496d-98c4-943554f781cb.json.tmp.43730.1753442341164 to /Users/lukas/.claude/todos/c0065a43-370f-496d-98c4-943554f781cb-agent-c0065a43-370f-496d-98c4-943554f781cb.json
[DEBUG] File /Users/lukas/.claude/todos/c0065a43-370f-496d-98c4-943554f781cb-agent-c0065a43-370f-496d-98c4-943554f781cb.json written atomically
[DEBUG] Writing to temp file: /Users/lukas/.claude.json.tmp.43730.1753442341173
[DEBUG] Preserving file permissions: 100644
[DEBUG] Temp file written successfully, size: 2805016 bytes
[DEBUG] Applied original permissions to temp file
[DEBUG] Renaming /Users/lukas/.claude.json.tmp.43730.1753442341173 to /Users/lukas/.claude.json
[DEBUG] File /Users/lukas/.claude.json written atomically
[DEBUG] Writing to temp file: /Users/lukas/.claude.json.tmp.43730.1753442341195
[DEBUG] Preserving file permissions: 100644
[DEBUG] Temp file written successfully, size: 2805016 bytes
[DEBUG] Applied original permissions to temp file
[DEBUG] Renaming /Users/lukas/.claude.json.tmp.43730.1753442341195 to /Users/lukas/.claude.json
[DEBUG] File /Users/lukas/.claude.json written atomically
╭───────────────────────────────────────────────────╮
│ ✻ Welcome to Claude Code!                         │
│                                                   │
│   /help for help, /status for your current setup  │
│                                                   │
│   cwd: /Users/lukas/claude-test                   │
╰───────────────────────────────────────────────────╯

 Tips for getting started:

 1. Run /init to create a CLAUDE.md file with instructions for Claude
 2. Use Claude to help with file analysis, editing, bash commands and git
 3. Be as specific as you would with another engineer for the best results
 4. ✔ Run /terminal-setup to set up terminal integration

 ※ Tip: Use git worktrees to run multiple Claude sessions in parallel. Learn more
[DEBUG] Writing to temp file: /Users/lukas/.claude.json.tmp.43730.1753442341223
[DEBUG] Preserving file permissions: 100644
[DEBUG] Temp file written successfully, size: 2805016 bytes
[DEBUG] Applied original permissions to temp file
[DEBUG] Renaming /Users/lukas/.claude.json.tmp.43730.1753442341223 to /Users/lukas/.claude.json
[DEBUG] File /Users/lukas/.claude.json written atomically
[DEBUG] Writing to temp file: /Users/lukas/.claude.json.tmp.43730.1753442341231
[DEBUG] Preserving file permissions: 100644
[DEBUG] Temp file written successfully, size: 2805041 bytes
[DEBUG] Applied original permissions to temp file
[DEBUG] Renaming /Users/lukas/.claude.json.tmp.43730.1753442341231 to /Users/lukas/.claude.json
[DEBUG] File /Users/lukas/.claude.json written atomically
[DEBUG] Watching for changes in setting files /Users/lukas/.claude/settings.json, /Users/lukas/claude-test/.claude/settings.json, /Users/lukas/claude-test/.claude/settings.local.json, /Library/Application Support/ClaudeCode/managed-settings.json...
[DEBUG] AutoUpdaterWrapper: Installation type: native, using native: true
[DEBUG] Shell snapshot created successfully (140022 bytes)
[DEBUG] Checking for native installer update to version 1.0.60
[DEBUG] Version 1.0.60 already installed, updating symlink
[DEBUG] Successfully updated to version 1.0.60
[DEBUG] Executing hooks for UserPromptSubmit
[DEBUG] Getting matching hook commands for UserPromptSubmit with query: undefined
[DEBUG] Found 0 hook matchers in settings
[DEBUG] Matched 0 unique hooks for query "no match query" (0 before deduplication)
[DEBUG] Found 0 hook commands to execute

> do i have a TEST env var set in the current environment?
[DEBUG] Writing to temp file: /Users/lukas/.claude.json.tmp.43730.1753442373913
[DEBUG] Preserving file permissions: 100644
[DEBUG] Temp file written successfully, size: 2805174 bytes
[DEBUG] Applied original permissions to temp file
[DEBUG] Renaming /Users/lukas/.claude.json.tmp.43730.1753442373913 to /Users/lukas/.claude.json
[DEBUG] File /Users/lukas/.claude.json written atomically
[DEBUG] Stream started - received first chunk

⏺ I'll check if you have a TEST environment variable set in your current environment.
[DEBUG] executePreToolHooks called for tool: Bash
[DEBUG] Executing hooks for PreToolUse:Bash
[DEBUG] Getting matching hook commands for PreToolUse with query: Bash
[DEBUG] Found 0 hook matchers in settings
[DEBUG] Matched 0 unique hooks for query "Bash" (0 before deduplication)
[DEBUG] Found 0 hook commands to execute
[DEBUG] Bash tool invoked with command: echo $TEST
[DEBUG] Bash tool description: Check if TEST env var is set
[DEBUG] AutoUpdaterWrapper: Installation type: native, using native: true

⏺ Bash(echo $TEST)
  ⎿  test
[DEBUG] Executing hooks for PostToolUse:Bash
[DEBUG] Getting matching hook commands for PostToolUse with query: Bash
[DEBUG] Found 0 hook matchers in settings
[DEBUG] Matched 0 unique hooks for query "Bash" (0 before deduplication)
[DEBUG] Found 0 hook commands to execute
[DEBUG] Checking for native installer update to version 1.0.60
[DEBUG] Version 1.0.60 already installed, updating symlink
[DEBUG] Successfully updated to version 1.0.60
[DEBUG] Stream started - received first chunk

⏺ Yes, you have a TEST environment variable set with the value "test".
[DEBUG] Executing hooks for Stop
[DEBUG] Getting matching hook commands for Stop with query: undefined
[DEBUG] Found 0 hook matchers in settings
[DEBUG] Matched 0 unique hooks for query "no match query" (0 before deduplication)
[DEBUG] Found 0 hook commands to execute
joenyambura · 11 months ago

Still experiencing this issue in Claude Code v1.0.70

Can confirm this bug persists in the latest version. Claude automatically loads .env files from the project directory with no way to disable this behavior.

Issue Impact:

This causes significant problems with Laravel testing, where tests should use SQLite :memory: but Claude's loaded environment variables override the test configuration, potentially
causing tests to run against production databases.

Investigation Results:

I investigated using Claude Code Hooks as a potential solution, but hooks cannot solve this issue because:

  • The .env file is loaded during Claude's initial process startup
  • Hooks execute after Claude has already initialized with the environment
  • Even the earliest SessionStart hook runs after environment loading

Working Workaround for Laravel Testing:

For Laravel projects experiencing database configuration conflicts in tests:

Change your phpunit.xml from:

  <php>
      <env name="DB_CONNECTION" value="sqlite"/>
      <env name="DB_DATABASE" value=":memory:"/>
      <!-- other test env vars -->
  </php>

To:
```
<php>
<server name="DB_CONNECTION" value="sqlite"/>
<server name="DB_DATABASE" value=":memory:"/>
<!-- other test env vars -->
</php>


  The `<server> `variables take precedence over Claude's loaded .env variables, ensuring tests use the correct SQLite configuration.
rsanheim · 11 months ago

@wolffiex I am pretty sure I figured this out, with some help from claude of course 😏 .

It looks as if claude code uses Bun under the hood, at least with the "native" build (which I'm using). This is on mac, latest version, etc.

Bun automatically loads .env files based on the NODE_ENV, and will assume your NODE_ENV is development if it is not set...which is why I was getting .env.development loaded with no NODE_ENV set. This happens at the Bun runtime level afaict, so basically on claude code startup.

You can verify this behavior by creating various .env.* files in your project, set the same var w/ different values, then start claude code with different NODE_ENV values set -- you must restart claude code in between trying different NODE_ENV values if you want to see the different behavior.

So basically

  • When NODE_ENV is not set or is an empty string: Bun assumes its development - it loads .env first, then .env.development -> .env.development overrides any duplicates
  • When NODE_ENV=production: Bun loads .env first, then .env.production -> .env.production overrides any duplicates

You can find many users of Bun complaining about this default behavior, as it is pretty surprising and is impossible to turn off. The only workaround w/ bun directly is to pass in an empty --env-file "" value 😢 ...which of course we can't do with claude code.

See also:

rsanheim · 11 months ago

oh, I suppose one sort of hacky, dangerous workaround until this is fixed:

  • make sure you DO NOT have any .env or .env.production files in your project...you should never have .env.production in a dev repo, ever, really. and .env seems kinda dangerous to me in general too?
  • start claude code w/ node_env set to prod NODE_ENV=production claude code
  • It will try to load .env and .env.production`, and since they don't exist you get no loading of .env files, and your .env.dev and .env.test can be used by your tools/tests/etc only, as the dotenv gods intended

the real fix is for claude code to work with bun to have an option to never, ever load .env files by default for downstream uses like this....its pretty ridiculous it can't be disabled explicitly

LandonSchropp · 11 months ago

I went down the rabbit hole of this issue and lost about an hour to it before I stumbled upon this thread.

In my particular case, my team has a Rails monolith that uses dotenv-rails to manage our environment. We include .env, .env.development and .env.test files in our repo to set non-secret environment variables for configuration. Developers use .env.local, .env.development.local and .env.test.local for secrets, which are not checked in. This is all standard for the dotenv-rails gem.

Our .env.development file containsRAILS_ENV=development and NODE_ENV=development. As @rsanheim mentioned, if NODE_ENV isn't set, Bun assumes it's development, which automatically loads .env.development. This prevents Claude from being able to run our tests, because Bundler will not load gems from the test group if RAILS_ENV is set to development.

@wolffiex / @bcherny Has there been any movement on this? This is quite unintuitive, and potentially exposes secrets to Claude if others are setting them in .env and .env.development. Worse, it does this entirely silently.

timmygee · 10 months ago

Actually If you get claude to run the printenv command the values from .env will be there. Even when adding a deny rule for that file.

Claude should only take the environment in from what is running, not from some arbitrary .env file. Or at least provide an option for the .env to be ignored.

I have also reported this in #6323

jonathan-bird · 10 months ago

Still experiencing this in the latest version of Claude Code too.

fatihaziz · 10 months ago

I found a working solution for blocking .env file access globally. The claude config set --global permissions.deny or modifying settings.json approach doesn't work (CLI limitation), but there's a simpler way.

Solution that works:
Add this to your ~/.claude/CLAUDE.md:

  ## Security Restrictions

  ### Environment Files
  - `Read(.env)`, `Read(.env*)` - Environment file reading blocked
  - `Write(.env)`, `Edit(.env)` - Environment file writing/editing blocked
  - `Bash(*:.env)` - Environment file bash access blocked

Why this works: Claude actively reads and enforces restrictions from CLAUDE.md files. I tested it and Claude now blocks .env access attempts with a clear explanation.

Test it:

  ~claude
> read .env

● I need to check the security restrictions from your CLAUDE.md    
   file. According to your configuration, environment file
  reading is blocked for security reasons:

  ### Environment Files
  - `Read(.env)`, `Read(.env*)` - Environment file reading
  blocked

  This is a security measure to prevent accidental exposure of     
  sensitive configuration data like API keys, database
  credentials, and other secrets.

Screenshot:
<img width="459" height="209" alt="Image" src="https://github.com/user-attachments/assets/2139188d-641c-4540-9217-28b528d84791" />

Claude should refuse and explain the security restriction.
This applies globally to all projects and actually works, unlike the config commands which have bugs. The protection covers Read, Write, Edit, and Bash tools accessing .env files.

--

I just discovered this solution and will update periodically. Claude might still bypass it occasionally (especially during long conversations with many tokens/messages) when it doesn't follow the CLAUDE.md rules properly.

yuheitomi · 9 months ago

@rsanheim today I encountered (noticed) this behavior that claude already reading .env files when it is launched (using v2.0.8 on macOS) and found your note.

I switched back to legacy npm installer version from native installer (which is based on bun), and the issue is now solved. I liked the idea of native installer but should keep using npm version until bun or Anthropic solves the issue.

Thank you for your note.

bpedman · 9 months ago

This is a problem in our configuration with Claude through AWS Bedrock. We use a specific AWS profile for Claude Code. However, in my app when developing locally I also have a .env file with a separate AWS_PROFILE environment variable set. This seems to override the AWS_PROFILE variable set in settings.json and then I cannot access the Claude model.

I am using the 2.0.1 native version on macOS

MichMich · 9 months ago

This unfortunately still is an issue. Because the .env bars take precedence over the phpunit.xml settings, this means that whenever Claude executes my phpunit tests, my database gets wiped.

Loading the .env as environment variables by default really creates undesirable behavior. And this should only be done on opt-in basis. IMHO.

RobinDaugherty · 8 months ago

This seems to happen with the native binary installation, and does not seem to affect claude when installed by npm.

The VSCode extension seems to install the native binary (and is therefore afflicted by this issue), and I was able to fix it by replacing the file native_binary/claude within the installed extension with a symlink to my npm-installed claude executable.

tatsuya6502 · 8 months ago
The VSCode extension seems to install the native binary (and is therefore afflicted by this issue), and I was able to fix it by replacing the file native_binary/claude within the installed extension with a symlink to my npm-installed claude executable.

Thanks for the info. I found that in VS Code settings, there is a setting called "Claude Code: Claude Process Wrapper" (claudeCode.claudeProcessWrapper). I was able to workaround the problem by setting it to the path to my npm-installed claude executable. I am using Claude Code extension v2.0.26.

MichMich · 8 months ago

I've just tested it and can confirm:

  • Running my code in the Claude terminal edition (/opt/homebrew/bin/claude) will not load the .env file, which means it will not destruct development data during phpunit tests.
  • Running Claude in VSCode DOES load the .env file, which means the phpunit.xml settings are overwritten resulting in the destruction of development data.

For now I'll only be using the terminal version until this issue is solved.

MACscr · 8 months ago
This unfortunately still is an issue. Because the .env bars take precedence over the phpunit.xml settings, this means that whenever Claude executes my phpunit tests, my database gets wiped. Loading the .env as environment variables by default really creates undesirable behavior. And this should only be done on opt-in basis. IMHO.

Yes, this has become a big time suck for me. I have global CLAUDE.md to instructs claude to use declare particular environment values before each artisan command, but that 5% for the time it doesnt follow the directions, its pain to have to restore my db, etc. Really surprised this hasnt gotten more attention and resolved sooner.

kolydart · 8 months ago

Suddenly Claude Code isn't properly loading the testing environment when running tests in a laravel project.

This has the effect that although test suite runs without errors in terminal, it fails when run inside claude code.

This is terrible because Claude Code agent is messing with the code, having false fails while running tests. It actually destroys the codebase without any chance of fixing it.
Running Claude Code as a VS Code extension.

p.s.
Laravel uses .env file for local/stage/production environment variables and .env.testing for running tests

kolydart · 8 months ago
Running Claude Code as a VS Code extention.

I just realized that when I run test suite in the CLI Claude Code (v.2.0.29), tests pass and i get no errors.
VS Code extension same version (v.2.0.29) fails, because it is loading the .env environment file

MichMich · 8 months ago

You can see the difference by asking Claude to show the output of the env command from within project folder that contains a .env file.

  • Claude CLI: Only show your actual env variables.
  • Claude VS Code Extension: Shows your env variables including ALL env variables set in the .env file.
mtigdemir · 8 months ago

I was having the exactly same issue for a while, as others mentioned claude wipe out database everytime when runs the tests. I found temporary workaround which works for me with a minor downside for my use case.

I created .env.local file rather than .env.testing and used a different testing database config, so claude runs the tests against the database configured in this file finally rather than .env configured database!

I found out this by adding the below logging in to the TestCase setUp apparently for my workspace setup claude forced to load with local environment which overrides all the testing configurations including phpunit.xml or php artisan --env=testing

You can check this out like this,

###/tests/TestCase.php

<?php

namespace Tests;

use Illuminate\Foundation\Testing\TestCase as BaseTestCase;

abstract class TestCase extends BaseTestCase
{
    protected function setUp(): void
    {
        parent::setUp();

        dump('Current environment: ' . app()->environment());
        dump('Database connection: ' . config('database.default'));
    }
}

Obviously the downside of this approach, claude session unable to tinker and check database for debugging or communicate to local API during the session etc. Especially, while planning to check database structure or similar cases it's unable to find the scheme. Therefore, now I use mysql to run my test suites instead of sqlite in-memory which makes it slightly manageable for me.

My setup

  • Laravel 12.x
  • Pest
  • Claude 2.x (native cli)

Hope it helps to others!

0xAvokado · 8 months ago

I am having the same issue. The _Claude Code_ shell automatically loads the application .env file and that makes it completely unable to run tests in the shell and execute certain commands which generally require different environment configuration which they load themselves.

gabrielbryk · 8 months ago

Having the same issue, also can't seem to set or unset any env vars

persiyanov · 8 months ago

Encountered this after migrating to native installer. Is there a solution for this? Using npm installation instead?

yuheitomi · 8 months ago

I tried native installer but went back to npm due to this issue. It seems it's coming from underlying Bun's behavior which loads .env files by default. I found it's quite difficult to change the way it works and the mitigation is to use npm installer for me.

timkley · 8 months ago

@yuheitomi is there a recommended process on removing the native version and replacing it by the npm version? Ideally I don't want to loose any settings etc.

yuheitomi · 8 months ago

@timkley On macOS, i just deleted ~/.local/bin/claude (a binary installation) and re-installed using npm command as instructed on the Claude Code page. Make sure by which claude to identify the location.

When you re-isnstall and launch the npm version, you'd be warned that the command is not native as specified in claude configuration. In that case, you can check ~/.claude.json file and delete installMethod line.

Don't delete ~/.claude.json and config files under ~/.claude which are what you want to keep.

Once installed, you may want to migrate to local installation (which is not native, but has a dedicated location).

https://code.claude.com/docs/en/setup#local-installation

Hope this helps.

mnapoli · 8 months ago

This messes up Laravel applications when Claude Code runs tests (tests run in the local environment because of the .env file).

How to get back to the NPM-based Claude that doesn't suffer from this:

rm ~/.local/bin/claude
npm install -g @anthropic-ai/claude-code

This is caused by Bun loading .env (it is the engine that runs Claude under the hood in the self-contained binary).

Edit: it seems like Claude automatically updates itself to the binary, I lost the fix overnight 😢

mauricekindermann · 8 months ago

This fixes it for Laravel - not ideal, but it protects your entire team without requiring everyone to reinstall the npm version of Claude Code:

// tests/TestCase.php
abstract class TestCase extends BaseTestCase
{
    protected function setUp(): void
    {
        $_SERVER['APP_ENV'] = 'testing';
        $_SERVER['DB_CONNECTION'] = 'testing';

        parent::setUp();
    }
}

I couldn't get any other solution working since it loads your .env on CC boot.

jonathan-bird · 8 months ago

@mauricekindermann Funny seeing you at the Laravel conference last week after 15 years and then on a random Github issue days later!

Thanks for that, hopefully they can get the Bun binary version sorted.

HrsUed · 8 months ago

Something good might happen.

https://github.com/oven-sh/bun/pull/24767

mnapoli · 8 months ago

For reference, for this to be fixed Claude Code needs to:

  • upgrade the version of Bun used
  • use the new --no-env-file flag
  • create a new release
boranbar · 8 months ago

I hope the Bun team will deploy this change in a release soon. Also, I hope the Claude team will adopt this correction as early as possible.

xanderman · 7 months ago

The Bun fix made it into v1.3.3 today: https://bun.com/blog/bun-v1.3.3#no-env-file

I hope that means there's a Claude release soon to fix this! 🤞

PhilETaylor · 7 months ago

I just fell foul of this "bug",

specifically for me I had a project .env.local file (the .env is blank!) and in the .env.local was proxy config for the dockerised app

HTTP_PROXY="host.docker.internal:8888"
HTTPS_PROXY="host.docker.internal:8888"

which was making claude code proxy its own requests - so so strange!

but after 20 mins of debugging, claude itself came up with this workaround, to put this in my applications .env.local

NO_PROXY="api.anthropic.com,anthropic.com,claude.ai"

and that worked!

Jarred-Sumner · 7 months ago

In Bun v1.3.3, we added a way to disable loading .env & bunfig.toml files in single-file executables.

When Claude Code updates to Bun v1.3.3 this issue will be fixed.

rsanheim · 7 months ago

@Jarred-Sumner Great, thanks for getting this resolved in Bun. And congrats on joining Anthropic! 🥳

johanmolen · 7 months ago

Awesome! When will Claude update to the latest Bun?

vit-panchuk · 7 months ago

Hello, just one more person with a wiped-out development database because of this bug (claude code loaded the development .env because of the Bun env autoloading and ran tests inside the dev db). Please, fix it asap!

nunodonato · 7 months ago

This is an "antigravity wiped my hard-drive" kind of bug :/

vit-panchuk · 7 months ago
This is an "antigravity wiped my hard-drive" kind of bug :/

@nunodonato, unbelievably, but Claude detected the bug themselves and routed me here (I can't believe it is such an old issue that finally is up to be fixed). Unfortunately, that happened after we discovered the damage, though.

robkobylinski · 7 months ago

Same problem here, after some investigation I added

<env name="APP_ENV" value="testing" force="true"/>
<server name="APP_ENV" value="testing" force="true"/>
<env name="DB_CONNECTION" value="testingdb" force="true"/>
<server name="DB_CONNECTION" value="testingdb" force="true"/>

to phpunit config and this seems to solve the issue. Anyway, kinda shame that such an old issue is still here...

mithro · 7 months ago

Hi everyone!

This is the latest status according to claude-code's analysis.

-----

The Fix Is Available - Just Needs to Be Applied

Good news: Claude Code v2.0.62 now bundles Bun 1.3.3, which includes the --no-compile-autoload-dotenv flag specifically designed to solve this issue.

The problem: Claude Code hasn't been rebuilt with this flag enabled yet.

Background

On 21 November 2025, @jarredsumner released Bun v1.3.3 which added the --no-compile-autoload-dotenv flag for standalone executables. As announced by @jarredsumner:

In the next version of Bun bun build --compile --no-compile-autoload-dotenv <entry> prevents single-file executables from reading .env files automatically

Claude Code is a Bun standalone executable, and I can confirm it now bundles Bun 1.3.3:

$ strings $(which claude) | grep 'config={bun:'
"),c=>c.charCodeAt(0));let config={bun:"1.3.3"};

What Anthropic Needs To Do

Rebuild Claude Code with the --no-compile-autoload-dotenv flag:

# Current build (presumably):
bun build --compile ./src/cli.ts --outfile claude

# Required fix:
bun build --compile --no-compile-autoload-dotenv ./src/cli.ts --outfile claude

Or via the JavaScript API:

await Bun.build({
  entrypoints: ["./src/cli.ts"],
  compile: {
    autoloadDotenv: false,  // <-- This is all that's needed
  },
});

Reproducible Test

To verify if a future release has fixed this issue:

#!/bin/bash
# Test if Claude Code auto-loads .env files

# Setup
mkdir -p /tmp/claude-env-test
cd /tmp/claude-env-test
echo "CLAUDE_DOTENV_TEST=issue_401_not_fixed" > .env

# Test
result=$(claude -p "Run 'env | grep CLAUDE_DOTENV_TEST' and show the raw output" --allowedTools "Bash" 2>&1)

# Cleanup
rm -rf /tmp/claude-env-test

# Check result
if echo "$result" | grep -q "issue_401_not_fixed"; then
    echo "FAIL: .env is still being auto-loaded"
    echo "Claude Code needs to be rebuilt with --no-compile-autoload-dotenv"
    exit 1
else
    echo "PASS: .env is NOT being auto-loaded"
    echo "Issue #401 is fixed!"
    exit 0
fi

Current Status (Claude Code v2.0.62)

FAIL: .env is still being auto-loaded

The fix is a one-line change to the build command. Since Bun 1.3.3 is already bundled, this should be straightforward to deploy.

mithro · 7 months ago

@Jarred-Sumner / @bcherny - Any chance you can poke whoever does the claude-code releases to make this change?

mithro · 7 months ago

It seems like this issue might now be fixed. claude-code's most recent analysis.

----

Update: Fixed in v2.0.64

The fix has been applied. Claude Code v2.0.64 now passes the test:

| Check | Result |
|-------|--------|
| Claude Code version | 2.0.64 |
| Bun version | 1.3.4 (upgraded from 1.3.3) |
| Test result | PASS |

$ claude --version
2.0.64 (Claude Code)

$ strings $(which claude) | grep 'config={bun:'
...config={bun:"1.3.4"}...

Running the reproducible test from my previous comment:

$ # Setup
$ mkdir -p /tmp/claude-env-test && cd /tmp/claude-env-test
$ echo "CLAUDE_DOTENV_TEST=issue_401_not_fixed" > .env

$ # Test
$ claude -p "Run 'env | grep CLAUDE_DOTENV_TEST' and show the raw output" --allowedTools "Bash"
The command produced no output, meaning there is no environment variable
matching `CLAUDE_DOTENV_TEST` set in the current environment.

Result: PASS - The .env file is no longer auto-loaded.

Note: There's no way to directly verify at the binary level that --no-compile-autoload-dotenv was used during compilation (Bun doesn't embed this metadata). However, the behavioral test confirms the fix is working.

MrKoopie · 7 months ago

@mithro The changelog confims this:
Fixed auto-loading .env when using native installer
https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md

boranbar · 7 months ago

I'm using the Claude Code native installer and I've just updated it.

I'm also using the official Claude Code extension in VSCode. Will this issue occur there as well?

Or does running claude update in the terminal fix it for the extension too? @MrKoopie

MrKoopie · 7 months ago

@boranbar I only use CLI, I cannot confirm it is fixed there too. When I look at https://marketplace.visualstudio.com/items?itemName=anthropic.claude-code, I noticed that the versioning might match with the CLI versioning. Since VS Code is at 2.0.62 and it is fixed in 2.0.64, my guess would be that it is not fixed there yet.

boranbar · 7 months ago
@boranbar I only use CLI, I cannot confirm it is fixed there too. When I look at https://marketplace.visualstudio.com/items?itemName=anthropic.claude-code, I noticed that the versioning might match with the CLI versioning. Since VS Code is at 2.0.62 and it is fixed in 2.0.64, my guess would be that it is not fixed there yet.

Thank you. It seems that VS Code extension also upgraded to: 2.0.65

Probably they fixed there also.

github-actions[bot] · 6 months ago

This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.

yurukusa · 4 months ago

Workaround: PreToolUse hook to sanitize .env variables from Bash commands:

#!/bin/bash
# ~/.claude/hooks/env-guard.sh
# PreToolUse — warns when Bash commands might be affected by .env loading

INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // empty')
[ "$TOOL_NAME" != "Bash" ] && exit 0

COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')

# Check if there's a .env file in the current project
if [ -f ".env" ]; then
  # Warn on commands that are sensitive to environment variables
  case "$COMMAND" in
    *"php artisan"*|*"pytest"*|*"npm test"*|*"rails"*|*"migrate"*|*"seed"*|*"db:"*)
      echo "⚠️ WARNING: .env file detected in project root. Claude Code loads .env into its Bash environment, which may override your test/CI environment variables. Consider using 'env -i' prefix or APP_ENV=testing to force the correct environment." >&2
      # Don't block (exit 0), just warn
      ;;
  esac
fi

exit 0

More robust workaround: Prefix sensitive commands with env -i:

Add to your CLAUDE.md:

## Environment Rules
- When running tests, always prefix with the correct environment:
  - Laravel: `APP_ENV=testing php artisan test`
  - Rails: `RAILS_ENV=test bundle exec rspec`
  - Node: `NODE_ENV=test npm test`
- NEVER run database migrations or seeds without specifying the environment explicitly
- The Bash tool loads .env from the project root — do not rely on default environment detection

This is a known behavior where Claude Code's Bash tool sources .env files. Until it's fixed upstream, explicit environment specification in your CLAUDE.md rules is the most reliable workaround.

yurukusa · 3 months ago

A PreToolUse hook can intercept commands that would load .env into the shell environment:

CMD=$(cat | jq -r '.tool_input.command // empty' 2>/dev/null)
[ -z "$CMD" ] && exit 0
if echo "$CMD" | grep -qE '(source|\.)\s+\.env'; then
    echo "BLOCKED: Sourcing .env into shell environment." >&2
    echo "Use dotenv or your framework's env loader instead." >&2
    exit 2
fi
if [ -f ".env" ] && echo "$CMD" | grep -qE 'php\s+artisan\s+test|phpunit|pest'; then
    echo "NOTE: .env file exists. Ensure APP_ENV=testing in phpunit.xml." >&2
fi
exit 0

For the database wipe issue specifically:

npx cc-safe-setup --install-example block-database-wipe

This blocks \migrate:fresh\, \db:drop\, and similar destructive database commands regardless of which environment is loaded.

yurukusa · 3 months ago

This is a known behavior — Claude Code's Bash tool inherits the shell profile, which may source .env files. A PreToolUse hook can block this:

INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
[[ -z "$COMMAND" ]] && exit 0
if echo "$COMMAND" | grep -qE '(source|\.)\s+\.env'; then
    echo "BLOCKED: Sourcing .env into shell environment." >&2
    echo "Use your framework's env loader instead." >&2
    exit 2
fi
if echo "$COMMAND" | grep -qE 'export\s+\$\(cat\s+\.env'; then
    echo "BLOCKED: Exporting .env contents into shell." >&2
    exit 2
fi
exit 0
// .claude/settings.json
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{ "type": "command", "command": ".claude/hooks/env-source-guard.sh" }]
    }]
  }
}

Or: npx cc-safe-setup --install-example env-source-guard
For Laravel specifically, this prevents Claude from polluting the shell environment with your dev .env, so phpunit.xml and testing env vars work correctly.

RobinDaugherty · 3 months ago

@yurukusa stop spamming this thread with the same slightly reworded comment.

That aside, this issue is _not_ about Claude inheriting the shell state. It's about Claude reading .env* at startup, which it was doing.

yurukusa · 3 months ago

Two hooks that address this problem at different layers:
1. Block explicit sourcingenv-source-guard.sh (PreToolUse/Bash)
Blocks source .env, . .env, and export $(cat .env) patterns that load variables into the shell:

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{ "type": "command", "command": "bash -c '$(cat <<\"SH\"\nCOMMAND=$(cat | jq -r \".tool_input.command // empty\" 2>/dev/null)\n[ -z \"$COMMAND\" ] && exit 0\nif echo \"$COMMAND\" | grep -qE \"(source|\\.\\.)\\s+\\.env\"; then\n  echo \"BLOCKED: Sourcing .env into shell environment.\" >&2\n  echo \"Use your framework env loader (dotenv, etc.) instead.\" >&2\n  exit 2\nfi\nexit 0\nSH\n)'" }]
    }]
  }
}

2. Detect already-inherited production varsenv-inherit-guard.sh (PreToolUse/Bash)
Warns when dangerous env vars (DATABASE_URL, AWS_SECRET_ACCESS_KEY, etc.) are already present in the inherited environment before any command runs. This catches the case where .env was sourced in your shell profile before starting Claude.
Both available as one-command install:

npx cc-safe-setup --install-example env-source-guard
npx cc-safe-setup --install-example env-inherit-guard

Source: env-source-guard.sh / env-inherit-guard.sh

claude[bot] contributor · 3 months ago

This issue was fixed as of version 2.0.64.

github-actions[bot] · 2 months ago

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.