{"record":{"id":"4f55a39d0ec2566d","repo":"paperclipai/paperclip","slug":"photon-attachment-chunks-arrived-out-of-order","errorCode":null,"errorMessage":"Photon attachment chunks arrived out of order","messagePattern":"Photon attachment chunks arrived out of order","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/src/services/photon/attachments.ts","lineNumber":154,"sourceCode":"          !Number.isSafeInteger(part.info.totalBytes) || part.info.totalBytes < 0 ||\n          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)","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/server/src/services/photon/attachments.ts#L136-L172","documentation":"During streaming, once companion (Live Photo video) chunks have started, no further primary image chunks are expected. If a primaryChunk arrives after companionStarted became true, the stream is malformed and this error is thrown (server/src/services/photon/attachments.ts:154). It protects against interleaved or corrupted multipart streams being concatenated into a wrong file.","triggerScenarios":"A Photon stream emits primaryChunk parts after companionChunk parts began, i.e. out-of-order interleaving in a live-photo transfer.","commonSituations":"Gateway/adapter bug emitting interleaved chunks for Live Photos; a stream replayed or multiplexed incorrectly; custom client implementation violating the Photon part ordering contract.","solutions":["Retry the download once; if transient, a fresh stream usually arrives in correct order.","Check the @photon-ai/advanced-imessage / gateway version for known chunk-ordering bugs and upgrade.","Skip Live Photo companion handling (or the attachment) if the source stream is persistently malformed.","File a bug with the Photon gateway team including the messageGuid/attachmentGuid if reproducible."],"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 chunks arrived out of order\") {\n    // one fresh-stream retry, then treat the attachment as unavailable\n  } else throw e;\n}","preventionTips":["Keep the @photon-ai/advanced-imessage client and gateway on compatible versions","Retry with a brand-new stream rather than re-reading a consumed one","Cap retries to avoid looping on persistently malformed streams"],"tags":["streaming","ordering","live-photo"],"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"}