{"record":{"id":"7473925781fdefc1","repo":"payloadcms/payload","slug":"the-folder-data-name-originaldoc-name-cont","errorCode":null,"errorMessage":"The folder \"${data.name || originalDoc.name}\" contains ${isFolder ? 'folders' : 'documents'} that still belong to the following collections: ${translatedLabels.join(', ')}","messagePattern":"The folder \"(.+?)\" contains (.+?) that still belong to the following collections: (.+?)","errorType":"http","errorClass":"APIError","httpStatus":400,"severity":"error","filePath":"packages/payload/src/hierarchy/hooks/ensureSafeCollectionsChange.ts","lineNumber":99,"sourceCode":"            if (childFoldersResult.totalDocs > 0) {\n              dependentCollection = foldersSlug\n            }\n          }\n        }\n\n        if (dependentCollection) {\n          const translatedLabels = newCollections.map((collectionSlug) => {\n            if (req.payload.collections[collectionSlug]?.config.labels.singular) {\n              return getTranslatedLabel(\n                req.payload.collections[collectionSlug]?.config.labels.plural,\n                req.i18n,\n              )\n            }\n            return collectionSlug\n          })\n\n          const isFolder = dependentCollection === foldersSlug\n          throw new APIError(\n            `The folder \"${data.name || originalDoc.name}\" contains ${isFolder ? 'folders' : 'documents'} that still belong to the following collections: ${translatedLabels.join(', ')}`,\n            400,\n          )\n        }\n\n        return data\n      }\n    } else if (\n      (data?.[typeFieldName] === null ||\n        (Array.isArray(data?.[typeFieldName]) && data?.[typeFieldName].length === 0)) &&\n      newParentDocID\n    ) {\n      // attempting to set the type to catch-all, so we need to ensure that the parent allows this\n      let parentFolder\n      if (typeof newParentDocID === 'string' || typeof newParentDocID === 'number') {\n        try {\n          parentFolder = await req.payload.findByID({\n            id: newParentDocID,","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/payload/src/hierarchy/hooks/ensureSafeCollectionsChange.ts#L81-L117","documentation":"Thrown by the ensureSafeCollectionsChange beforeValidate hook when a folder is having its allowed collection types narrowed (or its type set in a way that removes collections), but documents or child folders still reference the folder through those collections. HTTP 400 APIError.","triggerScenarios":"Updating a folder's hierarchyType array to remove 'posts' while documents whose folder field points at this folder still have collection 'posts'; likewise removing a type that a child folder still declares.","commonSituations":"Reorganising folder taxonomy without first moving or deleting the documents that depend on it; UI letting users narrow folder types while content is still attached.","solutions":["Move or delete the dependent documents/folders first, then narrow the folder's type list.","If the removal is intentional, reassign the affected documents to another folder in a prior step.","Surface the error's collection list to the user so they know what to clean up.","Disable the type-narrowing control when the folder is non-empty."],"exampleFix":"// before\nawait payload.update({ collection: 'payload-folders', id: folderId, data: { hierarchyType: ['pages'] } })\n\n// after — reassign dependents first\nawait payload.update({\n  collection: 'posts',\n  where: { folder: { equals: folderId } },\n  data: { folder: newFolderId },\n})\nawait payload.update({ collection: 'payload-folders', id: folderId, data: { hierarchyType: ['pages'] } })","handlingStrategy":"try-catch","validationCode":"for (const removed of removedCollections) {\n  const { totalDocs } = await payload.find({\n    collection: removed,\n    where: { [folderFieldName]: { equals: folderId } },\n    limit: 1,\n    overrideAccess: true,\n  })\n  if (totalDocs > 0) throw new Error(`${removed} still has docs here`)\n}","typeGuard":"function folderIsEmpty(counts: Record<string, number>): boolean {\n  return Object.values(counts).every((c) => c === 0)\n}","tryCatchPattern":"try {\n  await payload.update({ collection: foldersSlug, id: folderId, data })\n} catch (err) {\n  if (err instanceof APIError && err.statusCode === 400 && /still belong/.test(err.message)) {\n    return { error: err.message }\n  }\n  throw err\n}","preventionTips":["Reassign dependent documents before narrowing folder types.","Disable type-narrowing UI when the folder is non-empty."],"tags":["hierarchy","folders","validation","before-validate","api-error-400"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}