{"record":{"id":"43f2b8bd8e71cf04","repo":"pnpm/pnpm","slug":"invalid-catalogs-configuration","errorCode":"INVALID_CATALOGS_CONFIGURATION","errorMessage":"The 'default' catalog was defined multiple times. Use the 'catalog' field or 'catalogs.default', but not both.","messagePattern":"The 'default' catalog was defined multiple times\\. Use the 'catalog' field or 'catalogs\\.default', but not both\\.","errorType":"exception","errorClass":"PnpmError","httpStatus":null,"severity":"error","filePath":"pnpm11/catalogs/config/src/getCatalogsFromWorkspaceManifest.ts","lineNumber":32,"sourceCode":"  if (workspaceManifest == null) {\n    return {}\n  }\n\n  checkDefaultCatalogIsDefinedOnce(workspaceManifest)\n\n  return {\n    // If workspaceManifest.catalog is undefined, intentionally allow the spread\n    // below to overwrite it. The check above ensures only one or the either is\n    // defined.\n    default: workspaceManifest.catalog,\n\n    ...workspaceManifest.catalogs,\n  }\n}\n\nexport function checkDefaultCatalogIsDefinedOnce (manifest: Pick<WorkspaceManifest, 'catalog' | 'catalogs'>): void {\n  if (manifest.catalog != null && manifest.catalogs?.default != null) {\n    throw new PnpmError(\n      'INVALID_CATALOGS_CONFIGURATION',\n      'The \\'default\\' catalog was defined multiple times. Use the \\'catalog\\' field or \\'catalogs.default\\', but not both.')\n  }\n}\n","sourceCodeStart":14,"sourceCodeEnd":37,"githubUrl":"https://github.com/pnpm/pnpm/blob/5b11d3a15b9022a2109cb18ed96a5d652630371f/pnpm11/catalogs/config/src/getCatalogsFromWorkspaceManifest.ts#L14-L37","documentation":"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`.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\n# pnpm-workspace.yaml\ncatalog:\n  react: ^18.2.0\ncatalogs:\n  default:\n    react: ^18.2.0\n# after\n# pnpm-workspace.yaml\ncatalog:\n  react: ^18.2.0","handlingStrategy":"validation","validationCode":"function hasDuplicateDefaultCatalog (manifest) {\n  return manifest.catalog != null && manifest.catalogs?.default != null\n}\nif (hasDuplicateDefaultCatalog(yaml.parse(await fs.readFile('pnpm-workspace.yaml', 'utf8')))) {\n  throw new Error('Choose either `catalog` or `catalogs.default`, not both')\n}","typeGuard":"function isWorkspaceManifestWithDuplicateDefault (m: unknown): boolean {\n  if (typeof m !== 'object' || m === null) return false\n  const manifest = m as { catalog?: unknown, catalogs?: { default?: unknown } }\n  return manifest.catalog != null && manifest.catalogs?.default != null\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["config","workspace","catalogs","yaml"],"backgroundTag":null,"analyzedSha":"5b11d3a15b9022a2109cb18ed96a5d652630371f","analyzedAt":"2026-08-16T13:18:59.198Z","schemaVersion":2},"datasetVersion":"2026-08-16T18:17:16.020Z"}