{"record":{"id":"c7e0cf9f416750ca","repo":"paperclipai/paperclip","slug":"paperclip-runner-chat-attachment-read-size-mismatch","errorCode":"paperclip_runner_chat_attachment_read_size_mismatch","errorMessage":"paperclip_runner_chat_attachment_read_size_mismatch","messagePattern":"paperclip_runner_chat_attachment_read_size_mismatch","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/src/services/native-runtime/chat-attachment-read.ts","lineNumber":237,"sourceCode":"      .getObject(this.options.binding.companyId, source.objectKey)\n      .then((value) => {\n        if (signal.aborted) {\n          value.stream.destroy();\n          throw new Error(\"paperclip_runner_chat_attachment_read_aborted\");\n        }\n        object = value;\n        return value;\n      });\n    const read = (async () => {\n      const value = await acquiring;\n      const chunks: Buffer[] = [];\n      let length = 0;\n      try {\n        for await (const chunk of value.stream) {\n          const bytes = Buffer.from(chunk);\n          length += bytes.length;\n          if (length > source.byteSize || length > MAX_ATTACHMENT_BYTES)\n            throw new Error(\n              \"paperclip_runner_chat_attachment_read_size_mismatch\",\n            );\n          chunks.push(bytes);\n        }\n      } finally {\n        value.stream.destroy();\n      }\n      const body = Buffer.concat(chunks);\n      if (\n        length !== source.byteSize ||\n        createHash(\"sha256\").update(body).digest(\"hex\") !==\n          source.sha256.toLowerCase()\n      )\n        throw new Error(\n          \"paperclip_runner_chat_attachment_read_integrity_mismatch\",\n        );\n      return body;\n    })();","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/server/src/services/native-runtime/chat-attachment-read.ts#L219-L255","documentation":"While streaming the object, a running byte counter enforces both the expected source.byteSize and the global MAX_ATTACHMENT_BYTES cap; if either is exceeded mid-stream the stream is destroyed and this error is thrown. It prevents oversized or maliciously growing payloads from being staged into the workspace.","triggerScenarios":"Stored object is larger than the metadata's byteSize recorded at authorization time; attachment exceeds MAX_ATTACHMENT_BYTES; a corrupt/compromised storage object yields extra bytes.","commonSituations":"Metadata/object divergence after partial writes; uploading files larger than the configured attachment cap; storage objects tampered with or written by a buggy ingest path.","solutions":["Verify the stored object matches its metadata (size/hash) or re-upload the attachment.","Ensure uploads respect the MAX_ATTACHMENT_BYTES limit configured in attachment-types.","Re-run ingest so byteSize metadata reflects the actual object.","Investigate the storage writer if objects and metadata diverge repeatedly."],"exampleFix":"// before\nawait uploadAttachment(bigFile); // > MAX_ATTACHMENT_BYTES; later read throws\n// after\nif (bigFile.byteLength <= MAX_ATTACHMENT_BYTES) await uploadAttachment(bigFile);","handlingStrategy":"validation","validationCode":"if (declaredByteSize > MAX_ATTACHMENT_BYTES) throw new Error(\"attachment exceeds maximum allowed size\");","typeGuard":null,"tryCatchPattern":"try {\n  return await scope.read(input);\n} catch (e) {\n  if (e.message === \"paperclip_runner_chat_attachment_read_size_mismatch\") {\n    return { status: \"attachment_oversized_or_corrupt\" }; // do not retry\n  }\n  throw e;\n}","preventionTips":["Enforce MAX_ATTACHMENT_BYTES at upload/ingest time.","Keep byteSize metadata in sync with stored objects.","Fail fast on size checks before streaming large payloads.","Audit ingest paths that can write objects larger than their metadata."],"tags":["size-limit","integrity","payload"],"backgroundTag":"file-size-limit-exceeded","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"}