NousResearch/hermes-agent · warning
image too large (max ${mb} MB)
Error message
image too large (max ${mb} MB) What it means
uploadChatImage enforces a client-side size ceiling (MAX_IMAGE_BYTES) on pasted images before converting them to a data URL. The error message includes the computed MB limit. It prevents oversized payloads from being base64-embedded into a JSON POST to /api/chat/image-upload.
Source
Thrown at web/src/lib/chatImagePaste.ts:129
/**
* Upload a browser clipboard/drop image to ``HERMES_HOME/images`` via the
* dedicated chat upload endpoint and return the absolute gateway path.
*
* The dashboard Chat tab is an xterm mirror of a TUI running INSIDE the
* gateway. The container has no access to the browser's clipboard, so the
* server-side ``clipboard.paste`` path can never see a pasted image.
* Upload the bytes the browser already holds, then hand the path to the
* TUI's ``/image`` command.
*/
export async function uploadChatImage(
blob: Blob,
profile = "",
): Promise<ChatImageUploadResult> {
if (blob.size === 0) throw new Error("clipboard image is empty");
if (blob.size > MAX_IMAGE_BYTES) {
const mb = Math.round(MAX_IMAGE_BYTES / (1024 * 1024));
throw new Error(`image too large (max ${mb} MB)`);
}
const mime = blob.type || "image/png";
const ext = IMAGE_MIME_EXT[mime] || "png";
const filename =
blob instanceof File && blob.name
? blob.name
: `clipboard.${ext}`;
const file =
blob instanceof File
? blob
: new File([blob], filename, { type: mime });
const dataUrl = await fileToDataUrl(file);
const qs = profile ? `?profile=${encodeURIComponent(profile)}` : "";
const res = await authedFetch(`/api/chat/image-upload${qs}`, {
method: "POST",
headers: { "Content-Type": "application/json" },View on GitHub (pinned to c896c09c42)
Solutions
- Crop or downscale the image before pasting (e.g. take a region screenshot instead of full screen).
- Re-encode to JPEG to shrink the payload, or attach the file directly if the UI supports file attach.
- If you own the deployment and genuinely need larger images, raise the limit at both the client constant and any server body-size cap.
Example fix
// before await uploadChatImage(originalPngBlob) // after const smaller = await compressToJpeg(originalPngBlob, 0.8) await uploadChatImage(smaller)
Defensive patterns
Strategy: validation
Validate before calling
import { MAX_IMAGE_BYTES } from './chatImagePaste'
if (blob.size > MAX_IMAGE_BYTES) {
blob = await downscaleUntilUnder(blob, MAX_IMAGE_BYTES) // canvas resize / JPEG re-encode
} Type guard
const fitsUploadLimit = (b: Blob) => b.size > 0 && b.size <= MAX_IMAGE_BYTES
Try / catch
try {
await uploadChatImage(blob)
} catch (err) {
if (/too large/i.test(String(err))) { blob = await shrink(blob); await uploadChatImage(blob); return }
throw err
} Prevention
- Prefer region screenshots over full-screen captures on retina displays.
- Compress to JPEG before pasting when the payload is near the limit.
- Keep any reverse-proxy body limit at or above MAX_IMAGE_BYTES to avoid server-side 413s after client validation passes.
When it happens
Trigger: Pasting a screenshot or photo whose blob.size exceeds MAX_IMAGE_BYTES; common with full-screen 4K/retina screenshots or high-bit-depth PNGs.
Common situations: Multi-monitor retina screenshots, pasted lossless screenshots from pro tools, or scanned documents. Users on slow links also hit gateway body-size limits around the same threshold.
Related errors
- clipboard image is empty
- Could not read image
- text || HTTP ${res.status}
- image upload did not return a path
- Missing URL
AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14).
Data as JSON: /api/errors/96a1e0f04869455b.
Report an issue: GitHub.