{"record":{"id":"73a6127d39348d81","repo":"paperclipai/paperclip","slug":"photon-companion-metadata-is-missing","errorCode":null,"errorMessage":"Photon companion metadata is missing","messagePattern":"Photon companion metadata is missing","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/src/services/photon/attachments.ts","lineNumber":162,"sourceCode":"            (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(\n        \"attachment_not_ready\",\n        \"Photon attachment is still being prepared; retry download\",\n      );\n    if (attachment.totalBytes > 0 && length !== attachment.totalBytes)\n      throw new PhotonError(\n        \"attachment_not_ready\",\n        \"Photon attachment transfer is incomplete\",","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/server/src/services/photon/attachments.ts#L144-L180","documentation":"A companionChunk (Live Photo video part) may only arrive after a header established companionInfo. If a companionChunk arrives with header or companionInfo unset, this error is thrown (server/src/services/photon/attachments.ts:162) because the companion data cannot be validated or attributed.","triggerScenarios":"Stream emits part.type === \"companionChunk\" before the header part, or the header part carried no companionInfo despite companion chunks following.","commonSituations":"Gateway dropping the header frame for a Live Photo; companionInfo omitted because the header part was consumed by a previous (retried) stream read; protocol mismatch between gateway and client library versions.","solutions":["Retry with a fresh download stream; ensure the previous stream was fully closed before retrying.","Verify client/gateway version compatibility for Live Photo companion metadata framing.","If the companion is optional, prefer a client/path that returns the primary image alone when companion metadata is absent.","Report persistent cases to the Photon gateway team with messageGuid/attachmentGuid."],"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 companion metadata is missing\") {\n    // retry once with a fresh stream; otherwise accept primary-only image\n  } else throw e;\n}","preventionTips":["Fully close prior streams before opening a new download attempt","Keep gateway and client library versions aligned for Live Photo support","Design consumers to tolerate primary-image-only results when companions are unavailable"],"tags":["streaming","live-photo","protocol"],"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"}