{"record":{"id":"b0dfcbf38f74a0c8","repo":"can1357/oh-my-pi","slug":"imagekind-svg-the-img-selector-only-su","errorCode":null,"errorMessage":"imageKind === \"svg\" ? \"The ':img' selector only supports .svg and .svgz files.\" : `Read image file [${mimeType}] failed: unsupported image format.`","messagePattern":"imageKind === \"svg\" \\? \"The ':img' selector only supports \\.svg and \\.svgz files\\.\" : `Read image file \\[(.+?)\\] failed: unsupported image format\\.`","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/read.ts","lineNumber":864,"sourceCode":"\t\t\tconst sizeStr = formatBytes(fileSize);\n\t\t\tconst maxStr = formatBytes(MAX_IMAGE_SIZE);\n\t\t\tthrow new ToolError(`Image file too large: ${sizeStr} exceeds ${maxStr} limit.`);\n\t\t}\n\t\ttry {\n\t\t\tconst imageLoadOptions = {\n\t\t\t\tpath: readPath,\n\t\t\t\tcwd: this.session.cwd,\n\t\t\t\tautoResize: this.#autoResizeImages,\n\t\t\t\tmaxBytes: MAX_IMAGE_SIZE,\n\t\t\t\tresolvedPath: absolutePath,\n\t\t\t\texcludeWebP: webpExclusionForModel(this.session.getActiveModel?.()),\n\t\t\t};\n\t\t\tconst imageInput =\n\t\t\t\timageKind === \"svg\"\n\t\t\t\t\t? await loadSvgImageInput(imageLoadOptions)\n\t\t\t\t\t: await loadImageInput({ ...imageLoadOptions, detectedMimeType: mimeType });\n\t\t\tif (!imageInput) {\n\t\t\t\tthrow new ToolError(\n\t\t\t\t\timageKind === \"svg\"\n\t\t\t\t\t\t? \"The ':img' selector only supports .svg and .svgz files.\"\n\t\t\t\t\t\t: `Read image file [${mimeType}] failed: unsupported image format.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{ type: \"text\", text: imageInput.textNote },\n\t\t\t\t\t{ type: \"image\", data: imageInput.data, mimeType: imageInput.mimeType },\n\t\t\t\t],\n\t\t\t\tdetails: {},\n\t\t\t\tsourcePath: imageInput.resolvedPath,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\t// Both surface as an actionable tool error so the model can fix the input\n\t\t\t// instead of the corrupt/oversized payload entering the transcript.\n\t\t\tif (error instanceof ImageInputTooLargeError || error instanceof InvalidImageDataError) {\n\t\t\t\tthrow new ToolError(error.message);","sourceCodeStart":846,"sourceCodeEnd":882,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/read.ts#L846-L882","documentation":"After loading an image via loadImageInput or loadSvgImageInput, a falsy result means the decoder could not produce a vision-ready input: for the explicit ':img' SVG selector the file was not .svg/.svgz, and for regular images the detected format was unsupported/undecodable. The tool throws a ToolError with a selector-specific message rather than attaching garbage.","triggerScenarios":":img selector pointed at a non-SVG file (e.g. photo.png:img); a file whose detectedMimeType is not a decodable raster format (mismatched extension vs content); corrupted or zero-byte image where the loader returns null instead of throwing.","commonSituations":"Model/agent appending :img to a non-SVG path hoping to force image mode; files renamed to .png but actually BMP/TIFF/HEIC (unsupported formats); truncated downloads; SVG selector used on an SVG that fails rasterization so the loader returns null.","solutions":["Drop the ':img' selector for non-SVG files — plain paths are auto-detected as images.","Verify the file actually is the claimed format (file(1) / magic bytes) and re-export to PNG/JPEG if it is TIFF/BMP/HEIC.","Re-download or re-save corrupted/truncated images.","For SVGs, ensure the extension is .svg/.svgz and the markup is valid XML."],"exampleFix":"// before\nread('scan.tiff:img') // unsupported format\n// after\n$ `magick scan.tiff scan.png`\nread('scan.png')","handlingStrategy":"validation","validationCode":"import { fileTypeFromBuffer } from 'file-type';\nconst buf = await Bun.file(p).slice(0, 4100).arrayBuffer();\nconst ft = await fileTypeFromBuffer(Buffer.from(buf));\nconst ok = (ext: string, mime?: string | null) =>\n  ext === 'svg' || ext === 'svgz' ? true : ['image/png','image/jpeg','image/gif','image/webp'].includes(mime ?? '');\nif (!ok(p.split('.').pop() ?? '', ft?.mime)) throw new Error(`unsupported image format: ${ft?.mime ?? 'unknown'}`);","typeGuard":null,"tryCatchPattern":"try {\n  return await readTool.execute({ path: target });\n} catch (e) {\n  if (e instanceof ToolError && /unsupported image format|only supports .svg/.test(e.message)) {\n    const converted = await convertToPng(target); // magick/convert\n    return await readTool.execute({ path: converted });\n  }\n  throw e;\n}","preventionTips":["Don't append ':img' to non-SVG files; plain image paths are auto-detected.","Verify actual format via magic bytes, not file extension.","Convert TIFF/BMP/HEIC to PNG/JPEG before reading.","Re-download truncated images; check for zero-byte files."],"tags":["image","format","svg","decoding"],"backgroundTag":"unsupported-image-format","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}