pnpm/pnpm · error · InvalidWorkspaceManifestError

Expected catalog field to be an object, but found - array

Error message

Expected catalog field to be an object, but found - array

What it means

assertValidWorkspaceManifestCatalog (pnpm11/workspace/workspace-manifest-reader/src/catalogs.ts:17) validates the `catalog` field of pnpm-workspace.yaml: it must be an object mapping dependency alias to a version string. An array (the hardcoded first message), any other non-object type, or non-string entry values throw InvalidWorkspaceManifestError, which carries the code INVALID_WORKSPACE_CONFIGURATION (surfacing as ERR_PNPM_INVALID_WORKSPACE_CONFIGURATION).

Source

Thrown at pnpm11/workspace/workspace-manifest-reader/src/catalogs.ts:17

import { InvalidWorkspaceManifestError } from './errors/InvalidWorkspaceManifestError.js'

export interface WorkspaceNamedCatalogs {
  [catalogName: string]: WorkspaceCatalog
}

export interface WorkspaceCatalog {
  [dependencyName: string]: string
}

export function assertValidWorkspaceManifestCatalog (manifest: { packages?: readonly string[], catalog?: unknown }): asserts manifest is { catalog?: WorkspaceCatalog } {
  if (manifest.catalog == null) {
    return
  }

  if (Array.isArray(manifest.catalog)) {
    throw new InvalidWorkspaceManifestError('Expected catalog field to be an object, but found - array')
  }

  if (typeof manifest.catalog !== 'object') {
    throw new InvalidWorkspaceManifestError(`Expected catalog field to be an object, but found - ${typeof manifest.catalog}`)
  }

  for (const [alias, specifier] of Object.entries(manifest.catalog)) {
    if (typeof specifier !== 'string') {
      throw new InvalidWorkspaceManifestError(`Invalid catalog entry for ${alias}. Expected string, but found: ${typeof specifier}`)
    }
  }
}

export function assertValidWorkspaceManifestCatalogs (manifest: { packages?: readonly string[], catalogs?: unknown }): asserts manifest is { catalogs?: WorkspaceNamedCatalogs } {
  if (manifest.catalogs == null) {
    return
  }

View on GitHub (pinned to 6261b7f388)

Solutions

  1. Rewrite `catalog` as a mapping of alias to version string (see exampleFix).
  2. Quote version strings that contain YAML-special characters.
  3. Re-run `pnpm install` to confirm the manifest now parses and validates.

Example fix

# before (catalog as a list)
catalog:
  - lodash: ^4.17.21

# after (catalog as a map: alias -> version string)
catalog:
  lodash: ^4.17.21
Defensive patterns

Strategy: validation

Validate before calling

import { assertValidWorkspaceManifestCatalog } from '@pnpm/workspace.manifest-reader'

try {
  assertValidWorkspaceManifestCatalog(manifest)
} catch {
  // your own, earlier error - before install surfaces ERR_PNPM_INVALID_WORKSPACE_CONFIGURATION
  throw new Error('pnpm-workspace.yaml: catalog must be a map of alias -> version string')
}

Type guard

function isValidCatalog (value: unknown): value is Record<string, string> {
  if (value == null) return true
  if (typeof value !== 'object' || Array.isArray(value)) return false
  return Object.values(value).every((v) => typeof v === 'string')
}

Prevention

When it happens

Trigger: Writing `catalog:` as a YAML list (e.g. `- lodash: ^4.17.21`) instead of a mapping, or giving a catalog entry a nested map/number instead of a version string, then any pnpm command that loads the workspace manifest.

Common situations: First-time catalog authoring in YAML where list-of-pairs syntax feels natural; converting dependency lists into catalogs by copy-paste; YAML gotchas where a value parses as a map (e.g. version strings containing ': ').

Related errors


AI-assisted analysis of pnpm/pnpm@6261b7f388 (2026-08-17). Data as JSON: /api/errors/0759a94e54a51255. Report an issue: GitHub.