From e734407400eb0b499345ae619f790dca7ac7ed46 Mon Sep 17 00:00:00 2001 From: Jack DeVries Date: Wed, 26 Aug 2026 14:40:51 -0400 Subject: [PATCH] feat: silently ignore `.env` directories when loading config --- src/config.ts | 4 ++-- test/config.test.ts | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/config.ts b/src/config.ts index 1abfaa1d..e60a8272 100644 --- a/src/config.ts +++ b/src/config.ts @@ -81,7 +81,7 @@ async function loadConfig() { // Load .env files async function loadEnvFiles() { let envVars: Record = {} - if (await Deno.stat(".env").catch(() => null)) { + if ((await Deno.stat(".env").catch(() => null))?.isFile) { envVars = await load() } else { try { @@ -96,7 +96,7 @@ async function loadEnvFiles() { .trim() const gitRootEnvPath = join(gitRoot, ".env") - if (await Deno.stat(gitRootEnvPath).catch(() => null)) { + if ((await Deno.stat(gitRootEnvPath).catch(() => null))?.isFile) { envVars = await load({ envPath: gitRootEnvPath }) } } catch { diff --git a/test/config.test.ts b/test/config.test.ts index eb9084a1..124db00d 100644 --- a/test/config.test.ts +++ b/test/config.test.ts @@ -837,6 +837,21 @@ Deno.test("getOptionWithSource - process env wins over project .env and is class } }) +Deno.test("getOptionWithSource - a .env directory is ignored, not fatal", async () => { + // Some monorepos have a `.env` directory. Loading it must not crash startup + // (previously threw IsADirectory); it is silently ignored like a missing file. + const projectDir = await Deno.makeTempDir() + const home = await Deno.makeTempDir() + try { + await Deno.mkdir(`${projectDir}/.env`) + const result = await runTeamSourceSubprocess({ cwd: projectDir, home }) + assertEquals(result, null) + } finally { + await Deno.remove(projectDir, { recursive: true }) + await Deno.remove(home, { recursive: true }) + } +}) + Deno.test("getOptionWithSource - invalid project value shadows valid global value", async () => { // A present-but-invalid higher-precedence value must block fallback to a // lower-precedence source, matching the pre-split spread-merge behavior.