{"record":{"id":"5488e012c16a12c9","repo":"paperclipai/paperclip","slug":"image-exceeds-attachment-bound","errorCode":null,"errorMessage":"Image exceeds attachment bound","messagePattern":"Image exceeds attachment bound","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"server/src/services/chat-sdk-runtime.ts","lineNumber":2967,"sourceCode":"          const result = await Promise.race([\n            http.get(teamsInlineImageDownloadUrl(locator), {\n              responseType: \"arraybuffer\",\n              maxRedirects: 0,\n              maxContentLength: MAX_ATTACHMENT_BYTES,\n              maxBodyLength: MAX_ATTACHMENT_BYTES,\n              timeout: 10_000,\n              signal,\n            }),\n            deadline,\n          ]);\n          signal.throwIfAborted();\n          if (\n            !result.data ||\n            (!(result.data instanceof ArrayBuffer) &&\n              !ArrayBuffer.isView(result.data)) ||\n            result.data.byteLength > MAX_ATTACHMENT_BYTES\n          )\n            throw new Error(\"Image exceeds attachment bound\");\n          return Buffer.from(\n            result.data instanceof ArrayBuffer\n              ? new Uint8Array(result.data)\n              : result.data,\n          );\n        } catch {\n          throw new Error(\"Teams inline image download unavailable\");\n        } finally {\n          clearTimeout(timer);\n          signal.removeEventListener(\"abort\", rejectDeadline);\n        }\n      };\n\n      const attachment: Attachment = { ...metadata, fetchData: () => fetchData() };\n      this.teamsInlineImageDescriptors.set(attachment, normalized);\n      this.teamsInlineImageFetchers.set(attachment, fetchData);\n      return attachment;\n    }","sourceCodeStart":2949,"sourceCodeEnd":2985,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/server/src/services/chat-sdk-runtime.ts#L2949-L2985","documentation":"When downloading a Teams inline image, the runtime validates the response: result.data must exist, be an ArrayBuffer or ArrayBufferView, and not exceed MAX_ATTACHMENT_BYTES. Any violation throws 'Image exceeds attachment bound' (the message also fires when data is missing or of unexpected shape, since all three conditions share the throw). It guards memory against oversized or malformed attachment payloads.","triggerScenarios":"The Teams CDN/API returns image data larger than MAX_ATTACHMENT_BYTES, returns no data (falsy result.data), or returns a non-binary type that is neither ArrayBuffer nor ArrayBufferView.","commonSituations":"Users posting very large inline images in Teams; a Teams API change altering the response envelope so data lands in a different field; auth redirect returning HTML instead of binary (caught by the instanceof checks).","solutions":["Lower the image size before sending it through Teams (compress/resize) so it fits MAX_ATTACHMENT_BYTES","Raise MAX_ATTACHMENT_BYTES in configuration if the deployment policy allows larger attachments","Verify the download URL returns binary data and not an error page; confirm the fetcher's auth is valid","Handle the throw by replacing the attachment with a placeholder instead of failing the whole message"],"exampleFix":"// before\nconst buf = await runtime.fetchTeamsInlineImage(attachment, signal);\n// after\nlet buf;\ntry {\n  buf = await runtime.fetchTeamsInlineImage(attachment, signal);\n} catch {\n  buf = placeholderImageBuffer; // handle oversized/unavailable images gracefully\n}","handlingStrategy":"try-catch","validationCode":"// enforce a client-side cap before requesting\nconst MAX = MAX_ATTACHMENT_BYTES; // keep in sync with server bound","typeGuard":null,"tryCatchPattern":"try { return await runtime.fetchTeamsInlineImage(attachment, signal); } catch (e) { if ((e as Error).message === 'Image exceeds attachment bound') return placeholderBuffer; throw e; }","preventionTips":["Compress or resize large images upstream before sending via Teams","Keep MAX_ATTACHMENT_BYTES policy documented for users","Expect non-binary (HTML error page) responses from expired CDN links and treat them as unavailable"],"tags":["teams","attachments","size-limit","validation"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}