{"record":{"id":"20a5f9c6e17ea225","repo":"paperclipai/paperclip","slug":"photon-attachment-header-is-missing","errorCode":null,"errorMessage":"Photon attachment header is missing","messagePattern":"Photon attachment header is missing","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/src/services/photon/attachments.ts","lineNumber":155,"sourceCode":"          part.info.totalBytes > MAX_ATTACHMENT_BYTES\n        )\n          throw new Error(\"Photon attachment metadata changed\");\n        header = true;\n        companionInfo = part.companionInfo;\n        companionUnavailable = Boolean(\n          companionInfo &&\n            (companionInfo.kind !== \"live-photo-video\" ||\n              ![\"video/quicktime\", \"video/mp4\"].includes(\n                companionInfo.mimeType,\n              ) ||\n              !Number.isSafeInteger(companionInfo.totalBytes) ||\n              companionInfo.totalBytes <= 0 ||\n              companionInfo.totalBytes > MAX_ATTACHMENT_BYTES),\n        );\n      } else if (part.type === \"primaryChunk\") {\n        if (companionStarted)\n          throw new Error(\"Photon attachment chunks arrived out of order\");\n        if (!header) throw new Error(\"Photon attachment header is missing\");\n        length += part.data.length;\n        if (length > MAX_ATTACHMENT_BYTES)\n          throw new Error(\"Attachment exceeds the configured size limit\");\n        chunks.push(part.data);\n      } else if (part.type === \"companionChunk\") {\n        if (!header || !companionInfo)\n          throw new Error(\"Photon companion metadata is missing\");\n        companionStarted = true;\n        companionLength += part.data.length;\n        if (companionUnavailable || companionLength > MAX_ATTACHMENT_BYTES) {\n          companionUnavailable = true;\n          break;\n        }\n        companionChunks.push(part.data);\n      }\n    }\n    if (timedOut || !header || !length)\n      throw new PhotonError(","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/server/src/services/photon/attachments.ts#L137-L173","documentation":"Primary data chunks must only arrive after a header part that establishes metadata. If a primaryChunk arrives while header is still false, the stream had no header first, and this error is thrown (server/src/services/photon/attachments.ts:155).","triggerScenarios":"The download stream yields part.type === \"primaryChunk\" before any part.type === \"header\" part.","commonSituations":"Gateway emitting truncated streams missing the header frame; protocol/version mismatch between client library and gateway; stream resumed mid-transfer where the header was dropped.","solutions":["Retry the download with a fresh stream; transient truncation is usually recovered by re-requesting.","Verify the @photon-ai/advanced-imessage client and gateway are version-compatible (header frame support).","Confirm the attachment still exists and is downloadable via a fresh client.messages.get before streaming.","If persistent, treat the attachment as unavailable and surface a recoverable failure instead of retrying endlessly."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await downloadPhotonAttachment(client, lineId, locator);\n} catch (e) {\n  if (e instanceof Error && e.message === \"Photon attachment header is missing\") {\n    // fresh-stream retry with small backoff; escalate if persistent\n  } else throw e;\n}","preventionTips":["Retry with a fresh stream; header-less streams are usually transient truncations","Verify gateway/client protocol compatibility after upgrades","Confirm the attachment still exists via messages.get before streaming"],"tags":["streaming","protocol","attachments"],"backgroundTag":"unexpected-response-shape","analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-09-18T08:03:59.046Z","contentChangedAt":"2026-09-18T08:03:59.046Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}