siyuan-note/siyuan · error · Base64ImageSizeLimitError
batch
Error message
batch
What it means
addBase64ImageBatchSize accumulates the byte size of base64 images queued for a single upload batch. When the running total (currentBytes + fileBytes) exceeds BASE64_IMAGE_BATCH_MAX_BYTES, it throws a Base64ImageSizeLimitError with kind "batch", meaning the whole batch would exceed the configured size limit. This protects the editor from oversized upload payloads that would fail or time out.
Solutions
- Split the image into a new batch: flush/start a new upload batch before adding this file, keeping each batch under BASE64_IMAGE_BATCH_MAX_BYTES
- Catch Base64ImageSizeLimitError and surface a user-facing message telling them the batch exceeds the size limit and to upload fewer/smaller images at once
- Check the incoming fileBytes against BASE64_IMAGE_BATCH_MAX_BYTES before enqueueing and reject images that alone exceed the limit
- Compress or downscale the image before base64 encoding to reduce its byte size
Example fix
// before
let batchBytes = 0;
images.forEach(img => { batchBytes = addBase64ImageBatchSize(batchBytes, img.bytes); });
// after
let batchBytes = 0;
for (const img of images) {
if (batchBytes + img.bytes > BASE64_IMAGE_BATCH_MAX_BYTES) {
await flushBatch(); // start a new batch
batchBytes = 0;
}
batchBytes = addBase64ImageBatchSize(batchBytes, img.bytes);
} Defensive patterns
Strategy: validation
Validate before calling
function canAddToBatch(currentBytes, fileBytes) {
return currentBytes + fileBytes <= BASE64_IMAGE_BATCH_MAX_BYTES;
} Type guard
const isBase64ImageSizeLimitError = (e: unknown): e is Base64ImageSizeLimitError => e instanceof Base64ImageSizeLimitError && e.kind === "batch";
Try / catch
try {
totalBytes = addBase64ImageBatchSize(currentBytes, fileBytes);
} catch (e) {
if (e instanceof Base64ImageSizeLimitError) {
startNewBatch(); // flush and continue with a fresh batch
} else { throw e; }
} Prevention
- Check the sum against BASE64_IMAGE_BATCH_MAX_BYTES before calling
- Compress/resize images before base64 encoding
- Flush the batch as soon as it approaches the limit
- Reject single images larger than the whole batch limit up front
When it happens
Trigger: Calling addBase64ImageBatchSize with (currentBytes, fileBytes) whose sum exceeds BASE64_IMAGE_BATCH_MAX_BYTES, e.g. repeatedly adding large base64-encoded images (pasted screenshots) until the cumulative batch bytes pass the cap.
Common situations: Users paste many or very large screenshots into the editor; a plugin adds multiple base64 images to one upload queue; the batch limit is lowered via configuration while old queued images remain.
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
- BASE64_IMAGE_SIZE_LIMIT
- item
- Account authentication failed, please login again
- Agent capability name and description are required
- asset path is sensitive
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/a6a9b4bf704eb059.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/protyle/upload/base64File.ts:33
super(`Base64 image ${scope} size ${actualBytes} exceeds ${maxBytes} bytes`);
this.name = "Base64ImageSizeLimitError";
}
}
export const isBase64ImageSizeLimitError = (error: unknown): error is Base64ImageSizeLimitError =>
error instanceof Base64ImageSizeLimitError;
export const assertBase64ImageItemSize = (actualBytes: number, maxBytes?: number) => {
const itemMaxBytes = Math.min(maxBytes ?? BASE64_IMAGE_ITEM_MAX_BYTES, BASE64_IMAGE_ITEM_MAX_BYTES);
if (actualBytes > itemMaxBytes) {
throw new Base64ImageSizeLimitError("item", actualBytes, itemMaxBytes);
}
};
export const addBase64ImageBatchSize = (currentBytes: number, fileBytes: number) => {
const totalBytes = currentBytes + fileBytes;
if (totalBytes > BASE64_IMAGE_BATCH_MAX_BYTES) {
throw new Base64ImageSizeLimitError("batch", totalBytes, BASE64_IMAGE_BATCH_MAX_BYTES);
}
return totalBytes;
};
const startsWith = (bytes: Uint8Array, signature: number[]) =>
signature.every((value, index) => bytes[index] === value);
const detectBase64ImageFormat = (bytes: Uint8Array): IBase64ImageFormat | undefined => {
if (startsWith(bytes, [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])) {
return {extension: "png", mime: "image/png"};
}
if (startsWith(bytes, [0xFF, 0xD8, 0xFF])) {
return {extension: "jpg", mime: "image/jpeg"};
}
if (startsWith(bytes, [0x47, 0x49, 0x46, 0x38, 0x37, 0x61]) ||
startsWith(bytes, [0x47, 0x49, 0x46, 0x38, 0x39, 0x61])) {
return {extension: "gif", mime: "image/gif"};
}View on GitHub (pinned to 9f775e8a12)