[BUG] Claude loads my projects .env into its bash environment (!)
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
- Create an empty folder and create a
.envfile with the contents 'MY_SECRET_ENV=test' - Open terminal, navigate to the folder and run
claude - Ask Claude to
run env. Now you should see 'MY_SECRET_ENV=test ' listed in the output. This will not happen when you just typeenvin your own bash terminal.
Expected Behavior
Claude should not load my projects .env in its bash environment
Actual Behavior
See above.
64 Comments
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!
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.
cc @wolffiex for input
Noting that this still appears to be an issue as recent as v1.0.48
This is still an issue as of 1.0.58 (native install) - I'm seeing claude code load
.env.developmentfiles 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.developmentbut not in.env.test(which most dotenv libraries will load for test, ieNODE_ENV=testorRAILS_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:
the real bad case, which can blow away local data, as the process env vars will win:
And just to verify, and to be super clear here, it isn't my own bash profile, or something that
miseis doing or something. Here I spawn a newzshshell, which I don't use daily and so the profile is basically empty:@rsanheim interestingly my claude code wasn't including this file before but it started doing this few days ago. I also have
1.0.58version. 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.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?
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
.envinto the its environment? Or was this never explicit behavior?@wolffiex adding my debug log
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:
Working Workaround for Laravel Testing:
For Laravel projects experiencing database configuration conflicts in tests:
Change your phpunit.xml from:
To:
```
<php>
<server name="DB_CONNECTION" value="sqlite"/>
<server name="DB_DATABASE" value=":memory:"/>
<!-- other test env vars -->
</php>
@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.developmentloaded 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 differentNODE_ENVvalues set -- you must restart claude code in between trying different NODE_ENV values if you want to see the different behavior.So basically
NODE_ENVis not set or is an empty string: Bun assumes its development - it loads.envfirst, then.env.development->.env.developmentoverrides any duplicatesNODE_ENV=production: Bun loads.envfirst, then.env.production->.env.productionoverrides any duplicatesYou 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:
oh, I suppose one sort of hacky, dangerous workaround until this is fixed:
.envor.env.productionfiles in your project...you should never have.env.productionin a dev repo, ever, really. and.envseems kinda dangerous to me in general too?NODE_ENV=production claude code.envand .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 intendedthe 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
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.developmentand.env.testfiles in our repo to set non-secret environment variables for configuration. Developers use.env.local,.env.development.localand.env.test.localfor secrets, which are not checked in. This is all standard for the dotenv-rails gem.Our
.env.developmentfile containsRAILS_ENV=developmentandNODE_ENV=development. As @rsanheim mentioned, ifNODE_ENVisn't set, Bun assumes it'sdevelopment, which automatically loads.env.development. This prevents Claude from being able to run our tests, because Bundler will not load gems from thetestgroup ifRAILS_ENVis set todevelopment.@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
.envand.env.development. Worse, it does this entirely silently.Actually If you get claude to run the
printenvcommand the values from.envwill 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
.envfile. Or at least provide an option for the.envto be ignored.I have also reported this in #6323
Still experiencing this in the latest version of Claude Code too.
I found a working solution for blocking .env file access globally. The
claude config set --global permissions.denyor modifyingsettings.jsonapproach doesn't work (CLI limitation), but there's a simpler way.Solution that works:
Add this to your
~/.claude/CLAUDE.md: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:
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.
@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.
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
.envfile with a separateAWS_PROFILEenvironment variable set. This seems to override theAWS_PROFILEvariable set in settings.json and then I cannot access the Claude model.I am using the 2.0.1 native version on macOS
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.
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/claudewithin 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-installedclaudeexecutable. I am using Claude Code extensionv2.0.26.I've just tested it and can confirm:
/opt/homebrew/bin/claude) will not load the .env file, which means it will not destruct development data during phpunit tests.For now I'll only be using the terminal version until this issue is solved.
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.
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
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
You can see the difference by asking Claude to show the output of the
envcommand from within project folder that contains a.envfile..envfile.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.localfile rather than.env.testingand used a different testing database config, so claude runs the tests against the database configured in this file finally rather than.envconfigured database!I found out this by adding the below logging in to the
TestCase setUpapparently for my workspace setup claude forced to load withlocalenvironment which overrides all the testing configurations includingphpunit.xmlorphp artisan --env=testingYou can check this out like this,
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
Hope it helps to others!
I am having the same issue. The _Claude Code_ shell automatically loads the application
.envfile 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.Having the same issue, also can't seem to
setorunsetany env varsEncountered this after migrating to native installer. Is there a solution for this? Using npm installation instead?
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.
@yuheitomi is there a recommended process on removing the native version and replacing it by the
npmversion? Ideally I don't want to loose any settings etc.@timkley On macOS, i just deleted
~/.local/bin/claude(a binary installation) and re-installed usingnpmcommand as instructed on the Claude Code page. Make sure bywhich claudeto 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.jsonfile and deleteinstallMethodline.Don't delete
~/.claude.jsonand config files under~/.claudewhich 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.
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:
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 😢
This fixes it for Laravel - not ideal, but it protects your entire team without requiring everyone to reinstall the npm version of Claude Code:
I couldn't get any other solution working since it loads your .env on CC boot.
@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.
Something good might happen.
https://github.com/oven-sh/bun/pull/24767
For reference, for this to be fixed Claude Code needs to:
--no-env-fileflagI 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.
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! 🤞
I just fell foul of this "bug",
specifically for me I had a project
.env.localfile (the.envis blank!) and in the.env.localwas proxy config for the dockerised appwhich 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.localand that worked!
In Bun v1.3.3, we added a way to disable loading
.env&bunfig.tomlfiles in single-file executables.When Claude Code updates to Bun v1.3.3 this issue will be fixed.
@Jarred-Sumner Great, thanks for getting this resolved in Bun. And congrats on joining Anthropic! 🥳
Awesome! When will Claude update to the latest Bun?
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!
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.
Same problem here, after some investigation I added
to phpunit config and this seems to solve the issue. Anyway, kinda shame that such an old issue is still here...
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-dotenvflag 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-dotenvflag for standalone executables. As announced by @jarredsumner:Claude Code is a Bun standalone executable, and I can confirm it now bundles Bun 1.3.3:
What Anthropic Needs To Do
Rebuild Claude Code with the
--no-compile-autoload-dotenvflag:Or via the JavaScript API:
Reproducible Test
To verify if a future release has fixed this issue:
Current Status (Claude Code v2.0.62)
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.
@Jarred-Sumner / @bcherny - Any chance you can poke whoever does the claude-code releases to make this change?
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 |
Running the reproducible test from my previous comment:
Result: PASS - The
.envfile is no longer auto-loaded.Note: There's no way to directly verify at the binary level that
--no-compile-autoload-dotenvwas used during compilation (Bun doesn't embed this metadata). However, the behavioral test confirms the fix is working.@mithro The changelog confims this:
Fixed auto-loading .env when using native installer
https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md
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
@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.
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.
Workaround: PreToolUse hook to sanitize .env variables from Bash commands:
More robust workaround: Prefix sensitive commands with
env -i:Add to your CLAUDE.md:
This is a known behavior where Claude Code's Bash tool sources
.envfiles. Until it's fixed upstream, explicit environment specification in your CLAUDE.md rules is the most reliable workaround.A PreToolUse hook can intercept commands that would load .env into the shell environment:
For the database wipe issue specifically:
This blocks \
migrate:fresh\, \db:drop\, and similar destructive database commands regardless of which environment is loaded.This is a known behavior — Claude Code's Bash tool inherits the shell profile, which may source
.envfiles. A PreToolUse hook can block this:Or:
npx cc-safe-setup --install-example env-source-guardFor Laravel specifically, this prevents Claude from polluting the shell environment with your dev
.env, sophpunit.xmland testing env vars work correctly.@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.Two hooks that address this problem at different layers:
1. Block explicit sourcing —
env-source-guard.sh(PreToolUse/Bash)Blocks
source .env,. .env, andexport $(cat .env)patterns that load variables into the shell:2. Detect already-inherited production vars —
env-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:
Source: env-source-guard.sh / env-inherit-guard.sh
This issue was fixed as of version 2.0.64.
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.