{"record":{"id":"0ed6e26153fe0a1e","repo":"paperclipai/paperclip","slug":"attachment-attachment-id-exceeded-the-maxbyte","errorCode":null,"errorMessage":"attachment ${attachment.id} exceeded the ${maxBytes}-byte cap while reading","messagePattern":"attachment (.+?) exceeded the (.+?)-byte cap while reading","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/src/services/plugin-host-services.ts","lineNumber":2612,"sourceCode":"\n        const maxBytes = typeof params.maxBytes === \"number\" && params.maxBytes > 0 ? params.maxBytes : null;\n        if (maxBytes !== null && attachment.byteSize > maxBytes) {\n          throw new Error(\n            `attachment ${attachment.id} is ${attachment.byteSize} bytes, over the ${maxBytes}-byte cap`,\n          );\n        }\n\n        const object = await getStorageService().getObject(attachment.companyId, attachment.objectKey);\n        const chunks: Buffer[] = [];\n        let total = 0;\n        for await (const chunk of object.stream) {\n          const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n          total += buf.length;\n          // Defense in depth: enforce the cap during streaming too, so a\n          // metadata/object size mismatch can never exceed the requested cap.\n          if (maxBytes !== null && total > maxBytes) {\n            object.stream.destroy();\n            throw new Error(`attachment ${attachment.id} exceeded the ${maxBytes}-byte cap while reading`);\n          }\n          chunks.push(buf);\n        }\n        const bytes = Buffer.concat(chunks);\n\n        await logPluginActivity({\n          companyId,\n          action: \"issue.attachment.read\",\n          entityType: \"issue\",\n          entityId: attachment.issueId,\n          details: {\n            attachmentId: attachment.id,\n            byteSize: bytes.length,\n            contentType: attachment.contentType,\n          },\n        });\n\n        return {","sourceCodeStart":2594,"sourceCodeEnd":2630,"githubUrl":"https://github.com/paperclipai/paperclip/blob/a7e689b3c35347b529cb9f54c9b9a8575a3dcab6/server/src/services/plugin-host-services.ts#L2594-L2630","documentation":"While streaming attachment bytes from storage, the accumulated total exceeded the caller's maxBytes cap even though the recorded byteSize was within it (the record and object disagree, or the size changed). Reading aborts rather than exceed the limit.","triggerScenarios":"Thrown at server/src/services/plugin-host-services.ts:2603 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["The attachment grew past the cap during streaming read. Re-send a smaller file, or compress/chunk the content so total bytes stay under the cap."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"a7e689b3c35347b529cb9f54c9b9a8575a3dcab6","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}