payloadcms/payload · error · Error
Collection "${collectionSlug}" does not have hierarchy enabl
Error message
Collection "${collectionSlug}" does not have hierarchy enabled What it means
Thrown by getAncestors in the hierarchy utilities when the target collection's config has no `hierarchy` block. The function needs `hierarchyConfig.parentFieldName` (and a use-as-title field) to walk the ancestor chain, so a collection without hierarchy enabled cannot resolve ancestors. It is a hard precondition failure, not a data-missing case.
Source
Thrown at packages/payload/src/hierarchy/utils/getAncestors.ts:53
*
* 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] = {}
}
const cache = context.hierarchyAncestorCache[collectionSlug]
const ancestors: Ancestor[] = []
View on GitHub (pinned to 00c58b35c0)
Solutions
- Add `hierarchy: { parentFieldName: 'parent' }` to the collection's config so the hierarchy block exists.
- Verify the `collectionSlug` argument resolves to the intended tree collection before calling getAncestors.
- If the collection is genuinely flat, remove the getAncestors call from that code path or branch on whether hierarchy is enabled.
Example fix
// before
const ancestors = await getAncestors({ collectionSlug: 'pages', req })
// after
if (payload.collections['pages']?.config?.hierarchy) {
const ancestors = await getAncestors({ collectionSlug: 'pages', req })
} Defensive patterns
Strategy: validation
Validate before calling
import type { Payload } from 'payload'
function assertHierarchyEnabled(payload: Payload, slug: string): void {
const cfg = payload.collections[slug]?.config
if (!cfg) throw new Error(`Collection "${slug}" not found`)
if (!cfg.hierarchy) {
throw new Error(`Collection "${slug}" has no hierarchy; cannot call getAncestors`)
}
}
// before calling:
assertHierarchyEnabled(payload, 'pages')
await getAncestors({ collectionSlug: 'pages', req }) Type guard
function hasHierarchy(
cfg: { hierarchy?: unknown } | undefined,
): cfg is { hierarchy: Record<string, unknown> } {
return Boolean(cfg && cfg.hierarchy)
}
if (hasHierarchy(payload.collections['pages']?.config)) {
await getAncestors({ collectionSlug: 'pages', req })
} Try / catch
try {
const ancestors = await getAncestors({ collectionSlug, req })
} catch (err) {
if (err instanceof Error && err.message.includes('does not have hierarchy')) {
// collection is flat; skip ancestor resolution
} else throw err
} Prevention
- Centralize ancestor-walking behind a helper that pre-checks the hierarchy config.
- Keep a list of hierarchy-enabled slugs and validate against it before calling getAncestors.
- Add a config-build assertion that flags collections used in tree UIs but missing the hierarchy field.
When it happens
Trigger: Calling getAncestors({ collectionSlug, req, includeSelf }) where `payload.collections[collectionSlug].config.hierarchy` is undefined. This happens when the slug points to a flat (non-tree) collection, or the hierarchy plugin/field was never added to that collection's config.
Common situations: Enabling hierarchy on some collections but calling a generic ancestor helper against the wrong slug; renaming/removing the hierarchy field from a collection but leaving UI or code that still calls getAncestors; copying an ancestor-walking code block to a new collection that was never configured for hierarchy.
Related errors
- Collection with the slug ${globalSlug} was not found
- Collection config for ${join.field.collection.toString()} wa
- ERROR: Failed to retrieve collection with the slug "${collec
- ERROR: Failed to retrieve collection version model with the
- ERROR: Failed to retrieve collection model with the slug "${
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/c00059e95e149dec.
Report an issue: GitHub.