{"record":{"id":"5e502e243899159e","repo":"payloadcms/payload","slug":"hierarchy-parent-field-parentfieldname-in-col-5e502e","errorCode":null,"errorMessage":"Hierarchy parent field \"${parentFieldName}\" in collection \"${collectionConfig.slug}\" must have hasMany set to false","messagePattern":"Hierarchy parent field \"(.+?)\" in collection \"(.+?)\" must have hasMany set to false","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/payload/src/hierarchy/sanitizeHierarchyCollection.ts","lineNumber":62,"sourceCode":"  }\n\n  const parentFieldName = collectionConfig.hierarchy.parentFieldName ?? defaultParentFieldName\n\n  // Check if parent field already exists\n  const existingParentField = collectionConfig.fields.find(\n    (field) => fieldAffectsData(field) && field.name === parentFieldName,\n  )\n\n  if (existingParentField) {\n    // Validate existing parent field configuration\n    if (existingParentField.type !== 'relationship') {\n      throw new Error(\n        `Hierarchy parent field \"${parentFieldName}\" in collection \"${collectionConfig.slug}\" must be a relationship field`,\n      )\n    }\n\n    if (existingParentField.hasMany !== false) {\n      throw new Error(\n        `Hierarchy parent field \"${parentFieldName}\" in collection \"${collectionConfig.slug}\" must have hasMany set to false`,\n      )\n    }\n\n    if (existingParentField.localized === true) {\n      throw new Error(\n        `Hierarchy parent field \"${parentFieldName}\" in collection \"${collectionConfig.slug}\" cannot be localized. The parent relationship must be consistent across all locales.`,\n      )\n    }\n  } else {\n    // Auto-create parent field if it doesn't exist\n    // useHeaderButton defaults to true - parent selection via header button with miller columns\n    const useHeaderButton = collectionConfig.hierarchy.admin?.useHeaderButton ?? true\n\n    const parentField = buildParentField({\n      collectionSlug: collectionConfig.slug,\n      injectHeaderButton: useHeaderButton,\n      parentFieldName,","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/payload/src/hierarchy/sanitizeHierarchyCollection.ts#L44-L80","documentation":"Thrown at sanitisation by sanitizeHierarchyCollection when the existing parent field is a relationship but hasMany is not explicitly false (i.e. hasMany:true or undefined treated as a hasMany violation per the strict check). Hierarchy supports a single parent only, so a multi-value relationship is rejected.","triggerScenarios":"Declaring hierarchy on a collection whose existing parent relationship field has hasMany:true, or omitting hasMany:false so it does not satisfy the === false check.","commonSituations":"Reusing a prior many-to-many relationship field as the hierarchy parent; copying a field template that defaults hasMany to true.","solutions":["Set hasMany: false explicitly on the parent relationship field.","If you need a many-valued link, use a different field name and let hierarchy create its own single-valued parent.","Re-init Payload after the change."],"exampleFix":"// before\n{ name: 'parent', type: 'relationship', relationTo: 'pages', hasMany: true }\n\n// after\n{ name: 'parent', type: 'relationship', relationTo: 'pages', hasMany: false }","handlingStrategy":"validation","validationCode":"const existing = collectionConfig.fields.find(\n  (f) => fieldAffectsData(f) && f.name === parentFieldName,\n)\nif (existing && existing.hasMany !== false) {\n  throw new Error(`Field ${parentFieldName} must have hasMany: false`)\n}","typeGuard":"function isSingleRelationship(f: any): boolean {\n  return f?.type === 'relationship' && f?.hasMany === false\n}","tryCatchPattern":null,"preventionTips":["Always set hasMany:false explicitly on a reused parent field.","Avoid reusing a hasMany relationship as the hierarchy parent."],"tags":["hierarchy","config","sanitization","fields","relationship"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}