{"record":{"id":"4f8ce74664a42bc5","repo":"can1357/oh-my-pi","slug":"image-file-too-large-formatbytes-stat-size-ex","errorCode":null,"errorMessage":"Image file too large: ${formatBytes(stat.size)} exceeds ${formatBytes(maxBytes)} limit.","messagePattern":"Image file too large: (.+?) exceeds (.+?) limit\\.","errorType":"validation","errorClass":"ImageInputTooLargeError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/utils/image-loading.ts","lineNumber":461,"sourceCode":"\n/** Normalizes historical image blocks in an ephemeral provider request. */\nexport async function normalizeProviderContextImagesForModel(context: Context, model: Model): Promise<Context> {\n\tconst messages = await normalizeModelContextMessages(context.messages, model);\n\treturn messages === context.messages ? context : { ...context, messages };\n}\n\nexport async function loadImageInput(options: LoadImageInputOptions): Promise<LoadedImageInput | null> {\n\tconst maxBytes = options.maxBytes ?? MAX_IMAGE_INPUT_BYTES;\n\tconst resolvedPath = options.resolvedPath ?? resolveReadPath(options.path, options.cwd);\n\tconst metadata = options.detectedMimeType\n\t\t? { mimeType: options.detectedMimeType }\n\t\t: await readImageMetadata(resolvedPath);\n\tconst mimeType = metadata?.mimeType;\n\tif (!mimeType) return null;\n\n\tconst stat = await Bun.file(resolvedPath).stat();\n\tif (stat.size > maxBytes) {\n\t\tthrow new ImageInputTooLargeError(stat.size, maxBytes);\n\t}\n\n\tconst inputBuffer = await fs.readFile(resolvedPath);\n\treturn loadInMemoryImageInput({\n\t\timage: { type: \"image\", data: inputBuffer.toBase64(), mimeType },\n\t\tresolvedPath,\n\t\ttextNotePrefix: \"Read image file\",\n\t\tautoResize: options.autoResize,\n\t\tmaxBytes,\n\t\texcludeWebP: options.excludeWebP,\n\t});\n}\n\n/** Rasterizes an explicitly selected local SVG/SVGZ into a vision-model image input. */\nexport async function loadSvgImageInput(options: LoadImageInputOptions): Promise<LoadedImageInput | null> {\n\tconst resolvedPath = options.resolvedPath ?? resolveReadPath(options.path, options.cwd);\n\tconst extension = path.extname(resolvedPath).toLowerCase();\n\tif (extension !== \".svg\" && extension !== \".svgz\") return null;","sourceCodeStart":443,"sourceCodeEnd":479,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/utils/image-loading.ts#L443-L479","documentation":"loadImageInput stats the resolved file before reading and throws ImageInputTooLargeError if its size exceeds the effective maxBytes (options.maxBytes ?? MAX_IMAGE_INPUT_BYTES), preventing oversized images from being base64-encoded and sent to the provider.","triggerScenarios":"Calling loadImageInput(path, options) where stat.size of the file at resolvedPath is greater than maxBytes.","commonSituations":"User attaches a multi-megabyte screenshot or photo; caller passes a small maxBytes; large PNG exports from design tools; photos straight from a camera.","solutions":["Downscale or recompress the image file before loading (JPEG conversion, smaller dimensions).","Increase the maxBytes option at the call site.","Strip metadata (EXIF) to shrink the file.","Pre-check with fs.stat and inform the user the file exceeds the limit before calling load."],"exampleFix":"// before: await loadImageInput(\"/tmp/screenshot.png\"); // default limit  // after: downscale/re-encode (e.g. magick screenshot.png -resize 1568x1568> -quality 80 screenshot.jpg), then await loadImageInput(\"/tmp/screenshot.jpg\");","handlingStrategy":"validation","validationCode":"const stat = await fs.stat(resolvedPath); if (stat.size > maxBytes) throw new Error(`refusing to load ${resolvedPath}: ${stat.size} > ${maxBytes} bytes`);","typeGuard":null,"tryCatchPattern":"try { const img = await loadImageInput(resolvedPath, { maxBytes }); } catch (err) { if (err instanceof ImageInputTooLargeError) { await compressImage(resolvedPath); return loadImageInput(resolvedPath, { maxBytes }); } throw err; }","preventionTips":["Pre-flight fs.stat on user-supplied image paths.","Set explicit maxBytes at call sites rather than relying on MAX_IMAGE_INPUT_BYTES.","Keep an automatic downscale/recompress fallback for oversized inputs.","Educate tool callers (screenshots/photos are the usual offenders) about the size cap."],"tags":["image","file-size","validation"],"backgroundTag":"file-too-large","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}