pnpm/pnpm · error · PnpmError
INVALID_CATALOGS_CONFIGURATION
INVALID_CATALOGS_CONFIGURATION
Error message
The 'default' catalog was defined multiple times. Use the 'catalog' field or 'catalogs.default', but not both.
What it means
Configuration validation for pnpm-workspace.yaml catalogs: the default catalog may be declared either as the top-level `catalog` field or as `catalogs.default`, but not both. The two forms merge into the same slot (the spread of `catalogs` over a `default` seeded from `catalog`), so a dual declaration is ambiguous and rejected by `checkDefaultCatalogIsDefinedOnce`.
Source
Thrown at pnpm11/catalogs/config/src/getCatalogsFromWorkspaceManifest.ts:32
if (workspaceManifest == null) {
return {}
}
checkDefaultCatalogIsDefinedOnce(workspaceManifest)
return {
// If workspaceManifest.catalog is undefined, intentionally allow the spread
// below to overwrite it. The check above ensures only one or the either is
// defined.
default: workspaceManifest.catalog,
...workspaceManifest.catalogs,
}
}
export function checkDefaultCatalogIsDefinedOnce (manifest: Pick<WorkspaceManifest, 'catalog' | 'catalogs'>): void {
if (manifest.catalog != null && manifest.catalogs?.default != null) {
throw new PnpmError(
'INVALID_CATALOGS_CONFIGURATION',
'The \'default\' catalog was defined multiple times. Use the \'catalog\' field or \'catalogs.default\', but not both.')
}
}
View on GitHub (pinned to 5b11d3a15b)
Solutions
- Keep one form: either the top-level `catalog` field, or move all default entries under `catalogs.default` and delete `catalog`
- After merge conflicts in pnpm-workspace.yaml, re-read the catalogs section and remove the duplicate declaration
Example fix
# before
# pnpm-workspace.yaml
catalog:
react: ^18.2.0
catalogs:
default:
react: ^18.2.0
# after
# pnpm-workspace.yaml
catalog:
react: ^18.2.0 Defensive patterns
Strategy: validation
Validate before calling
function hasDuplicateDefaultCatalog (manifest) {
return manifest.catalog != null && manifest.catalogs?.default != null
}
if (hasDuplicateDefaultCatalog(yaml.parse(await fs.readFile('pnpm-workspace.yaml', 'utf8')))) {
throw new Error('Choose either `catalog` or `catalogs.default`, not both')
} Type guard
function isWorkspaceManifestWithDuplicateDefault (m: unknown): boolean {
if (typeof m !== 'object' || m === null) return false
const manifest = m as { catalog?: unknown, catalogs?: { default?: unknown } }
return manifest.catalog != null && manifest.catalogs?.default != null
} Prevention
- Standardize the workspace on one catalogs style (recommend `catalogs:` with named + default) in a lint or CI check
- Resolve pnpm-workspace.yaml merge conflicts by regenerating rather than concatenating both sides
When it happens
Trigger: A pnpm-workspace.yaml containing both `catalog:` with entries and `catalogs:` containing a `default` key. The check is a plain `manifest.catalog != null && manifest.catalogs?.default != null` test, so even an empty `catalogs.default: {}` alongside a `catalog` field triggers it.
Common situations: Migrating a workspace to named catalogs by adding a `catalogs` section while forgetting to fold the old `catalog` field into `catalogs.default`; merge conflicts in pnpm-workspace.yaml resolved by keeping both forms; documentation examples mixing the two syntaxes.
Related errors
- CONFIG_SET_NOT_A_PROJECT_SETTING
- PROJECT_CONFIG_NOT_AN_OBJECT
- PROJECT_CONFIG_INVALID_VALUE_TYPE
- PROJECT_CONFIG_UNSUPPORTED_FIELD
- PROJECT_CONFIGS_IS_NEITHER_OBJECT_NOR_ARRAY
AI-assisted analysis of pnpm/pnpm@5b11d3a15b (2026-08-16).
Data as JSON: /api/errors/43f2b8bd8e71cf04.
Report an issue: GitHub.