can1357/oh-my-pi · error · ToolError

Image file too large: ${sizeStr} exceeds ${maxStr} limit.

Error message

Image file too large: ${sizeStr} exceeds ${maxStr} limit.

What it means

The Read tool caps image payloads at MAX_IMAGE_SIZE before decoding/attaching them. When the file's byte size exceeds the cap, it throws a ToolError naming the actual size and the limit, so oversized binaries never enter the model transcript. The check runs in #loadImageContent before loadImageInput/loadSvgImageInput.

Source

Thrown at packages/coding-agent/src/tools/read.ts:848

				`- Bytes: ${fileSize} (${formatBytes(fileSize)})`,
				imageMetadata?.width !== undefined && imageMetadata.height !== undefined
					? `- Dimensions: ${imageMetadata.width}x${imageMetadata.height}`
					: "- Dimensions: unknown",
				imageMetadata?.channels !== undefined ? `- Channels: ${imageMetadata.channels}` : "- Channels: unknown",
				imageMetadata?.hasAlpha === true
					? "- Alpha: yes"
					: imageMetadata?.hasAlpha === false
						? "- Alpha: no"
						: "- Alpha: unknown",
				"",
				`If you want to analyze the image, call inspect_image with path="${inspectImagePath}" and a question describing what to inspect and the desired output format.`,
			];
			return { content: [{ type: "text", text: metadataLines.join("\n") }], details: {}, sourcePath: absolutePath };
		}
		if (fileSize > MAX_IMAGE_SIZE) {
			const sizeStr = formatBytes(fileSize);
			const maxStr = formatBytes(MAX_IMAGE_SIZE);
			throw new ToolError(`Image file too large: ${sizeStr} exceeds ${maxStr} limit.`);
		}
		try {
			const imageLoadOptions = {
				path: readPath,
				cwd: this.session.cwd,
				autoResize: this.#autoResizeImages,
				maxBytes: MAX_IMAGE_SIZE,
				resolvedPath: absolutePath,
				excludeWebP: webpExclusionForModel(this.session.getActiveModel?.()),
			};
			const imageInput =
				imageKind === "svg"
					? await loadSvgImageInput(imageLoadOptions)
					: await loadImageInput({ ...imageLoadOptions, detectedMimeType: mimeType });
			if (!imageInput) {
				throw new ToolError(
					imageKind === "svg"
						? "The ':img' selector only supports .svg and .svgz files."

View on GitHub (pinned to 9690622007)

Solutions

  1. Downscale or recompress the image (e.g. convert to a resized JPEG/WebP) and read that.
  2. Crop to the region of interest to cut bytes.
  3. Use inspect_image metadata mode, which reports MIME/dimensions without attaching pixels (and bypasses the size cap by design).
  4. If the pipeline controls capture, lower screenshot quality/scale at capture time.

Example fix

// before
read('/photos/IMG_4821.HEIC-converted.png') // 28 MB
// after
$ `magick /photos/IMG_4821.png -resize 1600x -quality 80 /tmp/img.png`
read('/tmp/img.png') // ~400 KB, under MAX_IMAGE_SIZE
Defensive patterns

Strategy: validation

Validate before calling

import { statSync } from 'node:fs';
const MAX_IMAGE_SIZE = 10 * 1024 * 1024; // match tool limit
const size = statSync(imgPath).size;
if (size > MAX_IMAGE_SIZE) {
  await $`magick ${imgPath} -resize 1600x -quality 80 ${imgPath}.small.jpg`;
  imgPath = `${imgPath}.small.jpg`;
}

Try / catch

try {
  return await readTool.execute({ path: imgPath });
} catch (e) {
  if (e instanceof ToolError && e.message.startsWith('Image file too large')) {
    const shrunk = await shrinkImage(imgPath);
    return await readTool.execute({ path: shrunk });
  }
  throw e;
}

Prevention

When it happens

Trigger: Reading any image file (png/jpg/webp/svg, plain path, local:// image, or :img selector) whose fileSize > MAX_IMAGE_SIZE; the pre-check at read.ts:845 fires before decode.

Common situations: High-resolution photos or screenshots from DSLR/screencapture; scans saved at 600dpi; uncompressed PNG exports; reading camera originals instead of resized copies.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/5796abbd2d497015. Report an issue: GitHub.