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

  1. Crop or downscale the image before pasting (e.g. take a region screenshot instead of full screen).
  2. Re-encode to JPEG to shrink the payload, or attach the file directly if the UI supports file attach.
  3. 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

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


AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14). Data as JSON: /api/errors/96a1e0f04869455b. Report an issue: GitHub.