Skip to content

loadEnv fails with "Cannot destructure property 'loadEnvConfig'" on Next.js 15.5+ #16674

@k-nagata2026

Description

@k-nagata2026

loadEnv fails with Cannot destructure property 'loadEnvConfig' of 'import_env.default' as it is undefined on Next.js 15.5+

Summary

payload/dist/bin/loadEnv.js does import nextEnvImport from '@next/env' and then destructures loadEnvConfig from it. On Next.js 15.5+ the @next/env package no longer exposes a default export — only named exports remain — so nextEnvImport is undefined when the module is loaded through certain interop paths, and the destructure throws.

This affects any tooling that imports payload/node (which re-exports loadEnv from bin/loadEnv.js), including running custom scripts that import payload.config via tsx.

Reproduction

  • payload@3.84.1
  • @payloadcms/db-vercel-postgres@3.84.1 (which transitively imports payload/node via @payloadcms/drizzle/utilities/blocksToJsonMigrator)
  • next@15.5.18 (pins @next/env@15.5.18)
  • tsx@4.21.0
  • Node.js v22.14

A script that does:

import { getPayload } from "payload";
import config from "../payload.config";
const payload = await getPayload({ config });

run via yarn dotenv -e .env.local -- tsx scripts/foo.ts produces:

TypeError: Cannot destructure property 'loadEnvConfig' of 'import_env.default' as it is undefined.
    at loadedEnvFiles (node_modules/payload/dist/bin/loadEnv.js:3:9)

Root cause

node_modules/@next/env/dist/index.js is a webpack-bundled CJS file whose module.exports is { initialEnv, updateInitialEnv, processEnv, resetEnv, loadEnvConfig } — there is no default property.

Verification:

node -e "console.log(require('@next/env').default)"
# => undefined
node -e "import('@next/env').then(m => console.log(typeof m.default, Object.keys(m)))"
# => object [ initialEnv, updateInitialEnv, processEnv, resetEnv, loadEnvConfig ]

Older Next.js (pre-15.5) exposed module.exports.default = ... for legacy default-import compatibility, so the existing Payload code happened to work. PR #7047 fixed an earlier instance of this on a different path, but the same anti-pattern remains in bin/loadEnv.js.

Proposed fix

-import nextEnvImport from '@next/env';
+import * as nextEnvImport from '@next/env';
 import { findUpSync } from '../utilities/findUp.js';
-const { loadEnvConfig } = nextEnvImport;
+const { loadEnvConfig } = nextEnvImport.default ?? nextEnvImport;

The ?? nextEnvImport fallback keeps backwards-compat with Next.js < 15.5 (where default is the namespace object), while supporting 15.5+ (where named exports live on the namespace itself).

I have this applied locally via patch-package and it resolves the error.

Environment

Package Version
payload 3.84.1
@payloadcms/next 3.84.1
@payloadcms/db-vercel-postgres 3.84.1
next 15.5.18
@next/env 15.5.18
tsx 4.21.0
Node.js 22.14.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions