{"record":{"id":"85fe001b1f7aec0a","repo":"spring-projects/spring-ai","slug":"unsupported-image-type-supported-types-image-p","errorCode":null,"errorMessage":"Unsupported image type: . Supported types: image/png, image/jpeg, image/gif, image/webp","messagePattern":"Unsupported image type: \\. Supported types: image/png, image/jpeg, image/gif, image/webp","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatModel.java","lineNumber":1456,"sourceCode":"\t\t\tsource = DocumentBlockParam.Source.ofBase64(Base64PdfSource.builder().data(data).build());\n\t\t}\n\t\treturn ContentBlockParam.ofDocument(DocumentBlockParam.builder().source(source).build());\n\t}\n\n\t/**\n\t * Converts a Spring MIME type to the SDK's {@link Base64ImageSource.MediaType}.\n\t * @param mimeType the Spring MIME type\n\t * @return the SDK media type enum value\n\t * @throws IllegalArgumentException if the image type is unsupported\n\t */\n\tprivate Base64ImageSource.MediaType toSdkImageMediaType(MimeType mimeType) {\n\t\tString subtype = mimeType.getSubtype();\n\t\treturn switch (subtype) {\n\t\t\tcase \"png\" -> Base64ImageSource.MediaType.IMAGE_PNG;\n\t\t\tcase \"jpeg\", \"jpg\" -> Base64ImageSource.MediaType.IMAGE_JPEG;\n\t\t\tcase \"gif\" -> Base64ImageSource.MediaType.IMAGE_GIF;\n\t\t\tcase \"webp\" -> Base64ImageSource.MediaType.IMAGE_WEBP;\n\t\t\tdefault -> throw new IllegalArgumentException(\"Unsupported image type: \" + mimeType\n\t\t\t\t\t+ \". Supported types: image/png, image/jpeg, image/gif, image/webp\");\n\t\t};\n\t}\n\n\t/**\n\t * Applies {@code disableParallelToolUse} to an existing {@link ToolChoice} by\n\t * rebuilding the appropriate subtype with the flag set to {@code true}.\n\t */\n\tprivate ToolChoice applyDisableParallelToolUse(ToolChoice toolChoice) {\n\t\tif (toolChoice.isAuto()) {\n\t\t\treturn ToolChoice.ofAuto(toolChoice.asAuto().toBuilder().disableParallelToolUse(true).build());\n\t\t}\n\t\telse if (toolChoice.isAny()) {\n\t\t\treturn ToolChoice.ofAny(toolChoice.asAny().toBuilder().disableParallelToolUse(true).build());\n\t\t}\n\t\telse if (toolChoice.isTool()) {\n\t\t\treturn ToolChoice.ofTool(toolChoice.asTool().toBuilder().disableParallelToolUse(true).build());\n\t\t}","sourceCodeStart":1438,"sourceCodeEnd":1474,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatModel.java#L1438-L1474","documentation":"Even when the MIME type is image/*, the Anthropic API only accepts four image subtypes: png, jpeg/jpg, gif and webp. AnthropicChatModel maps the subtype to a Base64ImageSource.MediaType enum and throws IllegalArgumentException for any other subtype (e.g. image/svg+xml, image/bmp, image/tiff, image/heic).","triggerScenarios":"Sending a Media with an image MIME type outside the supported set, such as image/svg+xml, image/bmp, image/tiff, image/x-icon or image/heic (iPhone photos) — the switch falls through to default and throws.","commonSituations":"Uploading screenshots in BMP or TIFF from legacy tools; passing SVG vector graphics; iOS HEIC photos forwarded directly; icon files (image/x-icon) attached to prompts.","solutions":["Convert the image to PNG or JPEG before sending (ImageIO.write or a library like Thumbnailator/TwelveMonkeys).","Re-encode SVG by rasterizing it to PNG (e.g. Batik) — Anthropic cannot ingest vector SVG.","Convert HEIC photos to JPEG on the client or server before building the Media.","Double-check the MIME type string for typos (e.g. 'image/jpg' actually works via the 'jpg' case, but 'image/pjpeg' does not)."],"exampleFix":"// before\nvar media = new Media(MimeType.valueOf(\"image/svg+xml\"), svgBytes);\n// after\nBufferedImage img = rasterize(svgBytes);\nByteArrayOutputStream out = new ByteArrayOutputStream();\nImageIO.write(img, \"png\", out);\nvar media = new Media(MimeType.valueOf(\"image/png\"), out.toByteArray());","handlingStrategy":"validation","validationCode":"Set<String> ok = Set.of(\"png\", \"jpeg\", \"jpg\", \"gif\", \"webp\");\nif (!\"image\".equals(mimeType.getType()) || !ok.contains(mimeType.getSubtype().toLowerCase())) {\n    throw new IllegalArgumentException(\"Convert image to png/jpeg/gif/webp: \" + mimeType);\n}","typeGuard":null,"tryCatchPattern":"try {\n    return client.call(prompt);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Unsupported image type\")) {\n        byte[] converted = convertToPng(media.getData());\n        return client.call(rebuildPromptWith(media, MimeType.valueOf(\"image/png\"), converted));\n    }\n    throw e;\n}","preventionTips":["Pre-convert HEIC/BMP/TIFF/SVG images to PNG or JPEG in an ingestion pipeline.","Validate image subtypes when accepting user uploads, not at LLM call time.","Document that Anthropic supports exactly png/jpeg/gif/webp."],"tags":["java","spring-ai","anthropic","unsupported-image-format","illegal-argument"],"backgroundTag":"unsupported-enum-value","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}