paperclipai/paperclip · error

Attachment exceeds the configured size limit

Error message

Attachment exceeds the configured size limit

What it means

Before streaming, the message's attachment metadata (attachment.totalBytes) is validated: it must be a safe non-negative integer no larger than MAX_ATTACHMENT_BYTES. Otherwise this error is thrown (server/src/services/photon/attachments.ts:102). It guards against downloading absurdly large or corrupt-size attachments.

Solutions

  1. Check the attachment's totalBytes against MAX_ATTACHMENT_BYTES before calling and skip attachments that are too large.
  2. Raise MAX_ATTACHMENT_BYTES in server/src/attachment-types.js if the limit is unintentionally small.
  3. Treat non-numeric/missing totalBytes as a metadata problem: re-sync message metadata from Photon before downloading.
  4. Ask the sender to resend as a smaller/compressed attachment when the size genuinely exceeds the cap.

Example fix

// before
await downloadPhotonAttachment(client, lineId, locator); // may throw for big files
// after
const att = message.raw.content.attachments.find(a => a.guid === locator.attachmentGuid);
if (att.totalBytes > MAX_ATTACHMENT_BYTES) return skipAttachment(att, "too large");
await downloadPhotonAttachment(client, lineId, locator);
Defensive patterns

Strategy: validation

Validate before calling

import { MAX_ATTACHMENT_BYTES } from "../attachment-types.js";
const att = message.raw.content.attachments.find(a => a.guid === locator.attachmentGuid);
if (!Number.isSafeInteger(att?.totalBytes) || att.totalBytes < 0 || att.totalBytes > MAX_ATTACHMENT_BYTES) {
  throw new Error(`attachment too large or invalid size: ${att?.totalBytes}`);
}

Try / catch

try {
  await downloadPhotonAttachment(client, lineId, locator);
} catch (e) {
  if (e instanceof Error && e.message === "Attachment exceeds the configured size limit") {
    // record and skip; do not retry
  } else throw e;
}

Prevention

When it happens

Trigger: attachment.totalBytes is undefined/NaN/not a safe integer, negative, or greater than MAX_ATTACHMENT_BYTES as configured in server/src/attachment-types.js.

Common situations: A user sends a multi-hundred-MB video exceeding the configured cap; Photon metadata is missing totalBytes for an older message format; misconfigured attachment-size limit lower than expected media sizes.

Understand the failure class

Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18). Data as JSON: /api/errors/309f83d542a7651a. Report an issue: GitHub.

Appendix: source

Thrown at server/src/services/photon/attachments.ts:102

  const attachment = source.content.attachments.find(
    (candidate) => candidate.guid === locator.attachmentGuid,
  );
  if (
    source.guid !== locator.messageGuid ||
    !source.chatGuids.includes(locator.chatGuid) ||
    !attachment ||
    attachment.isSticker ||
    attachment.isHidden
  )
    throw new Error(
      "Photon attachment does not belong to this message and chat",
    );
  if (
    !Number.isSafeInteger(attachment.totalBytes) ||
    attachment.totalBytes < 0 ||
    attachment.totalBytes > MAX_ATTACHMENT_BYTES
  )
    throw new Error("Attachment exceeds the configured size limit");
  const stream = client.attachments.downloadStream(locator.attachmentGuid);
  let timedOut = false;
  const timer = setTimeout(() => {
    timedOut = true;
    void stream.close();
  }, 30_000);
  timer.unref();
  const chunks: Uint8Array[] = [];
  let length = 0;
  let header = false;
  let companionInfo: CompanionInfo | undefined;
  let companionUnavailable = false;
  let companionStarted = false;
  let companionLength = 0;
  const companionChunks: Uint8Array[] = [];
  try {
    for await (const part of stream) {
      if (part.type === "header") {

View on GitHub (pinned to 3f1d897a7c)