Skip to content

feat: silently ignore .env directories when loading config - #265

Merged
schpetbot merged 1 commit into
schpet:mainfrom
jackarch-2:env-default-open-behavior
Aug 31, 2026
Merged

schpetbot merged 1 commit into
schpet:mainfrom
jackarch-2:env-default-open-behavior

Conversation

@jackarch-2

@jackarch-2 jackarch-2 commented Aug 26, 2026

Copy link
Copy Markdown

Closes #264.

@jackarch-2 jackarch-2 changed the title feat(#264): silently ignore .env directories when loading config feat: silently ignore .env directories when loading config Aug 26, 2026
@schpetbot
schpetbot merged commit 0362fe5 into schpet:main Aug 31, 2026
11 checks passed
schpetbot pushed a commit that referenced this pull request Aug 31, 2026
#265 stops the `IsADirectory` crash by requiring `.env` to be a regular file.
That check is right, and this builds on it rather than replacing it.

Two things it leaves open, both of which bite the setup in #264:

A `.env` written to be `source`d by a shell hangs the CLI outright. @std/dotenv
expands `$VAR` references in unquoted values using a `while` loop that never
terminates when a value refers to itself, so a single ordinary line like
`export PATH=$PATH:/opt/bin` spins forever at startup -- no error, no exit.
That is a worse failure than the crash #265 fixes, it is still present in the
latest @std/dotenv (0.225.8), and the reporter's files are exactly the
shell-sourced kind that contain it. Since the only keys we ever apply are
LINEAR_/GH_/GITHUB_, the fix is to drop every other line before parsing, which
removes the whole class of failure and also silences the parser's warnings
about keys that were never ours to complain about. An unquoted `$` reference
in one of our own keys is refused with a warning instead of expanded --
unexpanded references otherwise resolve to the literal string "undefined",
which is silent corruption of a config value. Quoted values are left alone,
since dotenv takes those literally and they cannot hang.

And skipping the file silently hides it. Both the issue and CLAUDE.md ask for
the opposite: the reporter explicitly said being entirely silent "may hide
deeper issues", and the project's rule is to never fail silently. So an
unusable candidate now prints one yellow warning on stderr -- never stdout, so
--json output and the completion scripts stay clean -- and the CLI continues.
`LINEAR_IGNORE_ENV_FILE=1` opts out entirely, so the warning is self-terminating
for a repo that will never have a dotenv-shaped .env.

Also folded in: an unreadable .env (mode 000) passed #265's isFile check and
then crashed in the read, so read and parse failures are caught too, and the
repository-root candidate goes through the same path instead of a near-copy of
it.
schpetbot pushed a commit that referenced this pull request Aug 31, 2026
#265 stops the `IsADirectory` crash by requiring `.env` to be a regular file.
That check is right, and this builds on it rather than replacing it.

Two things it leaves open, both of which bite the setup in #264:

A `.env` written to be `source`d by a shell hangs the CLI outright. @std/dotenv
expands `$VAR` references in unquoted values using a `while` loop that never
terminates when a value refers to itself, so a single ordinary line like
`export PATH=$PATH:/opt/bin` spins forever at startup -- no error, no exit.
That is a worse failure than the crash #265 fixes, it is still present in the
latest @std/dotenv (0.225.8), and the reporter's files are exactly the
shell-sourced kind that contain it. Since the only keys we ever apply are
LINEAR_/GH_/GITHUB_, the fix is to drop every other line before parsing, which
removes the whole class of failure and also silences the parser's warnings
about keys that were never ours to complain about. An unquoted `$` reference
in one of our own keys is refused with a warning instead of expanded --
unexpanded references otherwise resolve to the literal string "undefined",
which is silent corruption of a config value. Quoted values are left alone,
since dotenv takes those literally and they cannot hang.

And skipping the file silently hides it. Both the issue and CLAUDE.md ask for
the opposite: the reporter explicitly said being entirely silent "may hide
deeper issues", and the project's rule is to never fail silently. So an
unusable candidate now prints one yellow warning on stderr -- never stdout, so
--json output and the completion scripts stay clean -- and the CLI continues.
`LINEAR_IGNORE_ENV_FILE=1` opts out entirely, so the warning is self-terminating
for a repo that will never have a dotenv-shaped .env.

Also folded in: an unreadable .env (mode 000) passed #265's isFile check and
then crashed in the read, so read and parse failures are caught too, and the
repository-root candidate goes through the same path instead of a near-copy of
it.
@schpetbot

Copy link
Copy Markdown
Collaborator

Shipped in v2.6.0.

Thanks for the fix — your ?.isFile check shipped as-is, with #269 building on it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Crash on startup due to odd .env

2 participants