payloadcms/payload · error · Error

Collection "${collectionSlug}" not found

Error message

Collection "${collectionSlug}" not found

What it means

Thrown by getAncestors when payload.collections[collectionSlug] is undefined — the slug does not match any registered collection. It is the first guard before hierarchy config is read, so an unknown slug fails fast.

Source

Thrown at packages/payload/src/hierarchy/utils/getAncestors.ts:48

}

/**
 * Get ancestor chain for a hierarchical document.
 * Returns array of {id, title} from root to the document.
 *
 * Uses request context caching for efficiency when called multiple times.
 */
export async function getAncestors({
  id,
  collectionSlug,
  includeSelf = true,
  req,
}: GetAncestorsArgs): Promise<Ancestor[]> {
  const { payload, user } = req

  const collectionConfig = payload.collections[collectionSlug]?.config
  if (!collectionConfig) {
    throw new Error(`Collection "${collectionSlug}" not found`)
  }

  const hierarchyConfig = collectionConfig.hierarchy
  if (!hierarchyConfig) {
    throw new Error(`Collection "${collectionSlug}" does not have hierarchy enabled`)
  }

  const parentFieldName = hierarchyConfig.parentFieldName
  const { localized: isTitleLocalized, titleFieldName } = findUseAsTitleField(collectionConfig)

  // Initialize cache if needed
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const context = req.context as any
  if (!context.hierarchyAncestorCache) {
    context.hierarchyAncestorCache = {}
  }
  if (!context.hierarchyAncestorCache[collectionSlug]) {
    context.hierarchyAncestorCache[collectionSlug] = {}

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Validate collectionSlug against Object.keys(payload.collections) before calling.
  2. Use the typed CollectionSlug union at the call boundary.
  3. After renaming a collection, sweep all getAncestors call sites.
  4. Confirm payload.init() resolved.

Example fix

// before
const ancestors = await getAncestors({ collectionSlug: slug, id, req })

// after
if (!payload.collections[slug]?.config) {
  throw new Error(`Unknown collection: ${slug}`)
}
if (!payload.collections[slug].config.hierarchy) {
  throw new Error(`${slug} has no hierarchy`)
}
const ancestors = await getAncestors({ collectionSlug: slug, id, req })
Defensive patterns

Strategy: validation

Validate before calling

if (!payload.collections[collectionSlug]?.config) {
  throw new Error(`Unknown collection: ${collectionSlug}`)
}
if (!payload.collections[collectionSlug].config.hierarchy) {
  throw new Error(`${collectionSlug} has no hierarchy`)
}

Type guard

function isKnownHierarchyCollection(
  payload: Payload,
  slug: string,
): boolean {
  return Boolean(payload.collections[slug]?.config?.hierarchy)
}

Try / catch

try {
  return await getAncestors({ collectionSlug, id, req })
} catch (err) {
  if (err instanceof Error && /not found|does not have hierarchy/.test(err.message)) return []
  throw err
}

Prevention

When it happens

Trigger: Calling getAncestors({ collectionSlug: 'wrong', id, req }) with a slug that is not in payload.collections.

Common situations: Slug typo; renamed collection; calling before Payload init; dynamic slug from untrusted input.

Related errors


AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12). Data as JSON: /api/errors/9257c3861c71c4ac. Report an issue: GitHub.