Skip to content

dotenv: override does not behave correctly with watch enabled #61412

@arkon

Description

@arkon

Version

>= 24.12.0

Platform

Darwin MBP-M1-RJQ0.local 24.6.0 Darwin Kernel Version 24.6.0: Wed Nov  5 21:33:58 PST 2025; root:xnu-11417.140.69.705.2~1/RELEASE_ARM64_T6000 arm64

Subsystem

No response

What steps will reproduce the bug?

See https://github.com/arkon/nodejs-env-file-override-repro

When using --watch, subsequent env files do not override the prior ones as expected by the docs if using both --env-file and --env-file-if-exists:

Also, you can pass multiple --env-file arguments. Subsequent files override pre-existing variables defined in previous files.

=== 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

How often does it reproduce? Is there a required condition?

This is always reproducible when using --watch and mixing --env-file and --env-file-if-exists.

What is the expected behavior? Why is that the expected behavior?

Documented override behaviour, aligning with behaviour seen when not using --watch.

What do you see instead?

Subsequent env files do not override earlier ones.

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions