Skip to content

fix(@next/env): include dir in loadEnvConfig cache key#92054

Open
Shailesh93602 wants to merge 1 commit intovercel:canaryfrom
Shailesh93602:fix/load-env-config-dir-cache-key
Open

fix(@next/env): include dir in loadEnvConfig cache key#92054
Shailesh93602 wants to merge 1 commit intovercel:canaryfrom
Shailesh93602:fix/load-env-config-dir-cache-key

Conversation

@Shailesh93602
Copy link
Copy Markdown

What?

Include dir as part of the loadEnvConfig cache key in @next/env.

Why?

loadEnvConfig caches its result in module-level state, but the cache check only tested whether any load had happened — it never compared the dir argument:

// Before (broken)
if (combinedEnv && !forceReload) {
  return { combinedEnv, parsedEnv, loadedEnvFiles: cachedLoadedEnvFiles }
}

In a monorepo where .env lives at the workspace root, Next.js internally calls loadEnvConfig with the app directory first (no .env there, so loadedEnvFiles: []). When user code then calls it with the monorepo root — a common pattern to load shared env vars — it silently hits the stale cache and returns empty results. DATABASE_URL (and all other vars) are undefined with no error and no warning.

The only workaround was the undocumented forceReload: true 4th argument, which also requires passing undefined twice to reach it.

Reproduction: https://github.com/aynaitlamine/loadenvconfig-nextjs-issue-reproduction

How?

Added a module-level cachedDir variable. The cache is now only returned when cachedDir === dir, and cachedDir is updated whenever a fresh load runs. The forceReload path is unchanged.

// After (fixed)
if (combinedEnv && !forceReload && cachedDir === dir) {
  return { combinedEnv, parsedEnv, loadedEnvFiles: cachedLoadedEnvFiles }
}
  • Related issues linked using fixes #92040
  • Tests added: test/unit/load-env-config-dir-cache.test.ts

fixes #92040

The cache guard only checked whether a previous load had occurred — it
never compared the `dir` argument. In a monorepo where `.env` lives at
the workspace root, Next.js internally calls `loadEnvConfig` with the
app directory first (no `.env` found there). When user code then calls
it with the monorepo root, it silently returns the stale cached result
with `loadedEnvFiles: []` and all env vars `undefined` — no error, no
warning.

Fix by adding a `cachedDir` variable so the cache is only returned when
the directory matches. A changed `dir` triggers a fresh load instead of
returning the wrong cached result.

Workaround before this fix: pass `forceReload: true` as the 4th
argument, which is undocumented and requires two `undefined` placeholders
to reach.
@nextjs-bot
Copy link
Copy Markdown
Collaborator

Allow CI Workflow Run

  • approve CI run for commit: aa599bc

Note: this should only be enabled once the PR is ready to go and can only be enabled by a maintainer

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

loadEnvConfig silently ignores directory argument in monorepo due to internal cache

2 participants