When using --watch and mixing --env-file with --env-file-if-exists, subsequent env files do not override the prior ones as expected by the docs:
Also, you can pass multiple
--env-filearguments. Subsequent files override pre-existing variables defined in previous files.
Regression introduced in Node.js 24.12.0
The bug only occurs when:
- Using
--watchmode, AND - Mixing
--env-fileand--env-file-if-existsflags
Using only --env-file or only --env-file-if-exists works correctly.
| Flags used | Without --watch |
With --watch |
|---|---|---|
--env-file + --env-file |
✅ Works | ✅ Works |
--env-file-if-exists + --env-file-if-exists |
✅ Works | ✅ Works |
--env-file + --env-file-if-exists |
✅ Works | ❌ Broken (24.12+) |
Uses mise to change Node.js versions being tested.
./test-versions.shSlightly cleaned up output:
=== Test 1: --env-file + --env-file-if-exists ===
Without --watch:
v24.11.1 MY_VAR: from_dotenv_local
v24.12.0 MY_VAR: from_dotenv_local
v24.13.0 MY_VAR: from_dotenv_local
v25.3.0 MY_VAR: from_dotenv_local
With --watch:
v24.11.1 MY_VAR: from_dotenv_local
v24.12.0 MY_VAR: from_dotenv <-- BUG: should be from_dotenv_local
v24.13.0 MY_VAR: from_dotenv <-- BUG
v25.3.0 MY_VAR: from_dotenv <-- BUG
=== Test 2: --env-file + --env-file (works correctly) ===
Without --watch:
v24.11.1 MY_VAR: from_dotenv_local
v24.12.0 MY_VAR: from_dotenv_local
v24.13.0 MY_VAR: from_dotenv_local
v25.3.0 MY_VAR: from_dotenv_local
With --watch:
v24.11.1 MY_VAR: from_dotenv_local
v24.12.0 MY_VAR: from_dotenv_local
v24.13.0 MY_VAR: from_dotenv_local
v25.3.0 MY_VAR: from_dotenv_local
=== Test 3: --env-file-if-exists + --env-file-if-exists (works correctly) ===
Without --watch:
v24.11.1 MY_VAR: from_dotenv_local
v24.12.0 MY_VAR: from_dotenv_local
v24.13.0 MY_VAR: from_dotenv_local
v25.3.0 MY_VAR: from_dotenv_local
With --watch:
v24.11.1 MY_VAR: from_dotenv_local
v24.12.0 MY_VAR: from_dotenv_local
v24.13.0 MY_VAR: from_dotenv_local
v25.3.0 MY_VAR: from_dotenv_local