paperclipai/paperclip · error
HEIF exceeds the attachment byte limit
Error message
HEIF exceeds the attachment byte limit
What it means
validateHeifDimensions first checks that the body is non-empty and not larger than MAX_ATTACHMENT_BYTES before parsing any boxes. It throws when the HEIF payload is zero-length or exceeds the configured attachment byte cap, so oversized files are rejected before any structure parsing or native decoding.
Solutions
- Check body.length in the caller and return a 413 Payload Too Large with the allowed size before invoking validation.
- Configure or verify MAX_ATTACHMENT_BYTES in attachment-types.js to match your gateway's body-size limits (e.g. express.json({limit})).
- Fix the upload path producing empty buffers — verify the client actually streamed the bytes and Content-Length matches.
- Compress/resize the HEIC client-side (e.g. sips -s formatOptions 50%) to fit under the byte cap.
Example fix
// before
router.post('/attachments', async (req, res) => {
await validatePhotonImage(req.body, req.headers['content-type']);
});
// after
router.post('/attachments', async (req, res) => {
if (!req.body?.length || req.body.length > MAX_ATTACHMENT_BYTES)
return res.status(413).json({ error: 'attachment too large or empty' });
await validatePhotonImage(req.body, req.headers['content-type']);
}); Defensive patterns
Strategy: validation
Validate before calling
import { MAX_ATTACHMENT_BYTES } from './attachment-types.js';
export function isAttachmentWithinByteLimit(body?: Buffer | null): boolean {
return !!body && body.length > 0 && body.length <= MAX_ATTACHMENT_BYTES;
} Type guard
function hasBytes(body: Buffer | undefined | null): body is Buffer {
return Buffer.isBuffer(body) && body.length > 0;
} Try / catch
try {
await validatePhotonImage(body, contentType);
} catch (err) {
if (err instanceof Error && err.message === 'HEIF exceeds the attachment byte limit') {
return respond(413, `attachment must be between 1 byte and ${MAX_ATTACHMENT_BYTES} bytes`);
}
throw err;
} Prevention
- Check Content-Length against the byte cap before reading the full body
- Configure express/fastify body limits to MAX_ATTACHMENT_BYTES so oversized uploads never reach validation
- Verify upload completion client-side (byte count sent vs file size)
- Guard against empty buffers from failed multipart reads before calling validators
When it happens
Trigger: Calling validatePhotonImage with a HEIF content type and a Buffer that is empty (0 bytes) or whose length exceeds MAX_ATTACHMENT_BYTES (from server/src/attachment-types.js).
Common situations: Failed client uploads producing empty buffers (truncated request bodies, wrong Content-Length); users attaching 100MB+ HEIC video-like sequences; proxy/gateway limits stripping bodies.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- HEIF decoded image exceeds the pixel limit
- HEIF dimensions could not be verified
- HEIF image collection exceeds the pixel limit
- Bridge response body exceeded the configured size limit.
- CreateOS workspace preparation failed; the image must…
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/a97a52191afe10ba.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/photon/media.ts:67
if (
!width ||
!height ||
width > 16_384 ||
height > 16_384 ||
width * height > MAX_PIXELS
)
throw new Error("HEIF decoded image exceeds the pixel limit");
totalPixels += width * height;
if (totalPixels > MAX_PIXELS * 3 || ++dimensions > 512)
throw new Error("HEIF image collection exceeds the pixel limit");
} else if (["meta", "iprp", "ipco"].includes(type)) {
visit(content + (type === "meta" ? 4 : 0), at + size, depth + 1);
}
at += size;
}
};
if (!body.length || body.length > MAX_ATTACHMENT_BYTES)
throw new Error("HEIF exceeds the attachment byte limit");
visit(0, body.length, 0);
if (!branded || !dimensions)
throw new Error("HEIF dimensions could not be verified");
}
export async function validatePhotonImage(
body: Buffer,
contentType: string,
): Promise<void> {
if (!contentType.startsWith("image/")) return;
if (HEIF_CONTENT_TYPES.has(contentType)) return validateHeifDimensions(body);
const metadata = await sharp(body, {
limitInputPixels: MAX_PIXELS,
failOn: "error",
}).metadata();
if (
!metadata.width ||
!metadata.height ||View on GitHub (pinned to 3f1d897a7c)