{"record":{"id":"43513ce4ebaa5345","repo":"hcengineering/platform","slug":"cannot-import-attachment-without-parent-doc-doc","errorCode":null,"errorMessage":"Cannot import attachment without parent doc: ${docMeta.id}","messagePattern":"Cannot import attachment without parent doc: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/importer/src/notion/notion.ts","lineNumber":404,"sourceCode":"    notionParentId: dbPage.id,\n    name: docMeta.name,\n    notionId: docMeta.notionId,\n    mimeType: docMeta.mimeType,\n    size: docMeta.size\n  }\n  await importAttachment(client, fileUploader, data, attachment, space, dbPage)\n}\n\nasync function importAttachment (\n  client: TxOperations,\n  fileUploader: FileUploader,\n  data: Buffer,\n  docMeta: DocumentMetadata,\n  space: Ref<Teamspace>,\n  parentMeta?: DocumentMetadata\n): Promise<void> {\n  if (parentMeta === undefined) {\n    throw new Error('Cannot import attachment without parent doc: ' + docMeta.id)\n  }\n\n  const file = new File([new Uint8Array(data)], docMeta.name)\n  await fileUploader.uploadFile(docMeta.id, file)\n\n  const attachedData: AttachedData<Attachment> = {\n    file: docMeta.id as Ref<Blob>,\n    name: docMeta.name,\n    lastModified: Date.now(),\n    type: file.type,\n    size: file.size\n  }\n\n  await client.addCollection(\n    attachment.class.Attachment,\n    space,\n    parentMeta.id as Ref<Document>,\n    document.class.Document,","sourceCodeStart":386,"sourceCodeEnd":422,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/packages/importer/src/notion/notion.ts#L386-L422","documentation":"importAttachment uploads file bytes and then attaches them to a parent document via AttachedData built from parentMeta. Attachments cannot exist without a parent document, so when parentMeta is undefined the importer refuses to upload rather than creating an orphaned attachment.","triggerScenarios":"importAttachment called with parentMeta omitted — e.g. from createDBPageWithAttachments or importDBAttachment when the DB page lookup failed and parent metadata was passed through as undefined.","commonSituations":"Calling the attachment import API directly without resolving the parent page first; upstream importDBAttachment error paths that pass undefined parentMeta; attachments appearing in the export before/without their parent page metadata.","solutions":["Resolve the parent DocumentMetadata before calling importAttachment and pass it as parentMeta","Fix the caller (e.g. importDBAttachment flow) so a missing parent aborts earlier instead of passing undefined","Skip or defer attachments whose parent page metadata cannot be resolved","Ensure documentMetaMap is populated with parent pages before processing attachments"],"exampleFix":"// before\nawait importAttachment(client, fileUploader, data, docMeta, space)\n// after\nconst parentMeta = documentMetaMap.get(docMeta.notionParentId)\nif (parentMeta !== undefined) {\n  await importAttachment(client, fileUploader, data, docMeta, space, parentMeta)\n}","handlingStrategy":"validation","validationCode":"if (parentMeta === undefined) {\n  throw new Error('Skipping attachment ' + docMeta.id + ': no parent document resolved')\n}\nawait importAttachment(client, fileUploader, data, docMeta, space, parentMeta)","typeGuard":"function canAttach(docMeta, parentMeta) {\n  return parentMeta != null && typeof parentMeta.id === 'string'\n}","tryCatchPattern":"try {\n  await importAttachment(client, fileUploader, data, docMeta, space, parentMeta)\n} catch (err) {\n  if (err.message.startsWith('Cannot import attachment without parent doc: ')) {\n    console.warn('Orphan attachment skipped:', docMeta.id)\n    return\n  }\n  throw err\n}","preventionTips":["Resolve and pass parentMeta for every attachment upload","Abort or defer attachment processing when the parent page lookup fails instead of passing undefined","Ensure createDBPageWithAttachments completes page creation before attaching files","Log unresolved notionParentId values to detect gaps in metadata collection"],"tags":["notion","import","attachment"],"backgroundTag":"missing-parent-metadata","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}