payloadcms / payloadcms/payload

bin/loadEnv.js: default import on @next/env breaks under tsx CJS transpile

Open Beginner friendly
#16,683 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

stale
Dominant language
TypeScript
Stars
44.8k
Forks
4.2k
Avg merge
2d 21h
Merged PRs (30d)
53

Description

Bug

payload/dist/bin/loadEnv.js uses a default import on @next/env:

import nextEnvImport from '@next/env';
const { loadEnvConfig } = nextEnvImport;

@next/env is a webpack-bundled namespace module that exports only named
exports (loadEnvConfig, initialEnv, processEnv, resetEnv,
updateInitialEnv) with __esModule: true and no default property.

When this file is transpiled to CJS by tsx/esbuild (e.g. when running a
TypeScript script that imports getPayload and @payloadcms/drizzle
transitively pulls in payload/node), esbuild's __toESM helper sees the
__esModule: true marker and does not synthesize a default export.
Result: nextEnvImport is undefined, the destructure throws at module
load time, the entire chain crashes before any user code runs.

Repro

  1. Project on next@16 + payload@3.84.1 + @payloadcms/db-postgres.
  2. A TS script seed.ts:
import { getPayload } from 'payload'
import config from './payload.config'
await getPayload({ config })
  1. Run:
node --env-file=.env.local node_modules/tsx/dist/cli.mjs seed.ts

Crash:

TypeError: Cannot destructure property 'loadEnvConfig' of 'import_env.default' as it is undefined.
    at .../payload/dist/bin/loadEnv.js:3:9
    at Object.<anonymous> (.../payload/dist/bin/loadEnv.js:6:21)
    at Module._compile (node:internal/modules/cjs/loader:1705:14)
    at Object.transformer (.../tsx/dist/register-DJgoUG_Q.cjs:9:1709)

Fix

Use a namespace import. The destructure target becomes the namespace
object (which exposes the named exports directly) and the interop bug
disappears in both CJS and ESM:

import * as nextEnv from '@next/env';
const { loadEnvConfig } = nextEnv;

One file, two lines. Diff:

diff --git a/node_modules/payload/dist/bin/loadEnv.js b/node_modules/payload/dist/bin/loadEnv.js
index b61ecc1..58eaeda 100644
--- a/node_modules/payload/dist/bin/loadEnv.js
+++ b/node_modules/payload/dist/bin/loadEnv.js
@@ -1,6 +1,6 @@
-import nextEnvImport from '@next/env';
+import * as nextEnv from '@next/env';
 import { findUpSync } from '../utilities/findUp.js';
-const { loadEnvConfig } = nextEnvImport;
+const { loadEnvConfig } = nextEnv;
 /**
  * Try to find user's env files and load it. Uses the same algorithm next.js uses to parse env files, meaning this also supports .env.local, .env.development, .env.production, etc.
  */ export function loadEnv(path) {

(The source .ts file mirrors the same change: replace
import nextEnvImport from '@next/env' with
import * as nextEnv from '@next/env' and update the destructure.)

Workaround (until released)

patch-package with the diff above, applied via postinstall.

Environment

  • payload@3.84.1
  • next@16.2.6 (pulls @next/env@16.2.6)
  • payload bundles @next/env@15.5.18 — bug present in both versions
  • tsx@4.19.x
  • Node 22.x

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with bin/loadEnv.js and locate the corresponding source .ts file that imports @next/env. Reproduce the failure with the provided tsx command and verify the import and destructuring change against both CJS and ESM usage. Done means the seed.ts example loads without the module-load TypeError.

Written by the indexing model from the issue text.

Assessment

Tech stack
next.js, node.js, typescript
Domain
backend, tooling
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.