payloadcms/payload · error · Error
Could not find ExportDefaultDeclaration in next.config.js
Error message
Could not find ExportDefaultDeclaration in next.config.js
What it means
While parsing an ESM next.config.js, esprima-next found neither an ExportDefaultDeclaration nor an ExportNamedDeclaration in the AST body, so there is no export to wrap with withPayload. The message names only ExportDefaultDeclaration but the guard also covers named exports.
Source
Thrown at packages/create-payload-app/src/lib/wrap-next-config.ts:85
)
return { modifiedConfigContent, success: true }
}
return Promise.resolve({
modifiedConfigContent: content,
success: false,
})
} else if (configType === 'esm') {
const exportDefaultDeclaration = ast.body.find(
(p) => p.type === Syntax.ExportDefaultDeclaration,
) as Directive | undefined
const exportNamedDeclaration = ast.body.find(
(p) => p.type === Syntax.ExportNamedDeclaration,
) as ExportNamedDeclaration | undefined
if (!exportDefaultDeclaration && !exportNamedDeclaration) {
throw new Error('Could not find ExportDefaultDeclaration in next.config.js')
}
if (exportDefaultDeclaration && exportDefaultDeclaration.declaration?.loc) {
const modifiedConfigContent = insertBeforeAndAfter(
content,
exportDefaultDeclaration.declaration.loc,
)
return { modifiedConfigContent, success: true }
} else if (exportNamedDeclaration) {
const exportSpecifier = exportNamedDeclaration.specifiers.find(
(s) =>
s.type === 'ExportSpecifier' &&
s.exported?.name === 'default' &&
s.local?.type === 'Identifier' &&
s.local?.name,
)
if (exportSpecifier) {View on GitHub (pinned to 00c58b35c0)
Solutions
- Open next.config.js and ensure it has `export default { ... }` (ESM) so withPayload can wrap it.
- If the project actually uses CommonJS, ensure the file/extension detection picks the cjs path (rename to next.config.cjs or set type accordingly).
- As a fallback, follow the printed instructions to manually wrap the config with withPayload.
- Run the CLI on a clean, standard Next.js config first to confirm, then port your customizations.
Example fix
// before — next.config.js with no export
console.log('config loading')
// after
import { withPayload } from '@payloadcms/next/withPayload'
const nextConfig = {
// your config
}
export default withPayload(nextConfig) Defensive patterns
Strategy: validation
Validate before calling
import fs from 'fs'
function assertNextConfigHasExport(configPath: string) {
const src = fs.readFileSync(configPath, 'utf8')
if (!/export\s+default\b/.test(src) && !/export\s+\{/.test(src)) {
throw new Error(`${configPath} has no export default or named export — cannot wrap with withPayload`)
}
} Try / catch
try {
await wrapNextConfig({ nextConfigPath, nextConfigType: 'esm' })
} catch (e) {
if (e instanceof Error && e.message.includes('ExportDefaultDeclaration')) {
console.error('Manually wrap your next.config.js export with withPayload (see printed instructions).')
}
throw e
} Prevention
- Keep next.config.js as a standard `export default { ... }`.
- If using CommonJS, name the file next.config.cjs so detection picks the cjs branch.
- Run init on a clean standard config first, then port customizations.
When it happens
Trigger: create-payload-app init/upgrade on a Next.js project whose next.config.js (detected as ESM) has no export default or export statement — e.g. a config file that only assigns globals, re-exports via dynamic import, or was left as a stub.
Common situations: A next.config.js that exports nothing (side-effect only); a config already using a non-standard pattern; accidental CJS syntax in a .js file treated as ESM; a manually emptied config.
Related errors
- Invalid template given
- Invalid database type given. Valid types are: ${Object.value
- No package.json found in this project
- Payload is not installed in this project
- Failed to download: ${url}
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/284b53cfbc84cad8.
Report an issue: GitHub.