{"record":{"id":"71e41d08ac9a5365","repo":"spring-projects/spring-ai","slug":"invalid-video-content-type","errorCode":null,"errorMessage":"Invalid video content type: ","messagePattern":"Invalid video content type: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModel.java","lineNumber":523,"sourceCode":"\t\t\tVideoSource videoSource = null;\n\t\t\tif (media.getData() instanceof byte[] bytes) {\n\t\t\t\tvideoSource = VideoSource.builder().bytes(SdkBytes.fromByteArrayUnsafe(bytes)).build();\n\t\t\t}\n\t\t\telse if (media.getData() instanceof String uriText) {\n\t\t\t\tvideoSource = VideoSource.builder().s3Location(S3Location.builder().uri(uriText).build()).build();\n\t\t\t}\n\t\t\telse if (media.getData() instanceof URL url) {\n\t\t\t\ttry {\n\t\t\t\t\tvideoSource = VideoSource.builder()\n\t\t\t\t\t\t.s3Location(S3Location.builder().uri(url.toURI().toString()).build())\n\t\t\t\t\t\t.build();\n\t\t\t\t}\n\t\t\t\tcatch (URISyntaxException e) {\n\t\t\t\t\tthrow new IllegalArgumentException(e);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthrow new IllegalArgumentException(\"Invalid video content type: \" + media.getData().getClass());\n\t\t\t}\n\n\t\t\treturn ContentBlock.fromVideo(VideoBlock.builder().source(videoSource).format(videoFormat).build());\n\t\t}\n\t\telse if (BedrockMediaFormat.isSupportedImageFormat(mimeType)) { // Image\n\t\t\tImageSource.Builder sourceBuilder = ImageSource.builder();\n\t\t\tif (media.getData() instanceof byte[] bytes) {\n\t\t\t\tsourceBuilder.bytes(SdkBytes.fromByteArrayUnsafe(bytes)).build();\n\t\t\t}\n\t\t\telse if (media.getData() instanceof String text) {\n\n\t\t\t\tif (text.startsWith(\"s3://\")) {\n\t\t\t\t\tsourceBuilder.s3Location(S3Location.builder().uri(text).build()).build();\n\t\t\t\t}\n\t\t\t\telse if (text.startsWith(\"http://\") || text.startsWith(\"https://\")) {\n\t\t\t\t\t// Not base64\n\t\t\t\t\tif (URLValidator.isValidURLStrict(text)) {\n\t\t\t\t\t\ttry {","sourceCodeStart":505,"sourceCodeEnd":541,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModel.java#L505-L541","documentation":"BedrockProxyChatModel.mapMediaToContentBlock converts Media for video content into a Bedrock VideoBlock. Video data must arrive as a supported content representation (e.g. byte[]/Resource with a known MIME type); when media.getData() is of a class the mapper cannot turn into a video source, it throws IllegalArgumentException 'Invalid video content type: ' + the data class.","triggerScenarios":"Building a UserMessage with Media whose getData() returns an unsupported object type (e.g. a URL wrapper or custom object instead of byte[]/Resource) while the media MIME type is classified as video; calling chat with video media built via an unsupported data holder.","commonSituations":"Passing remote video URLs as Media data when the mapper only accepts raw bytes/Resource for video; using a Media factory variant that stores data as a generic object; tests that throw with loopback/FTP/IMDS URLs to verify URL fetching is blocked.","solutions":["Provide video content as byte[] or as a Resource so the mapper can build the VideoBlock source.","Download the video bytes yourself and construct Media with the raw data plus the correct MIME type (e.g. video/mp4).","Verify the MIME type/classification: if the content is actually an image or document, use the appropriate Media constructor so it routes to the right branch.","Check the supported Bedrock video formats (mp4/mov/mkv/webm) and that your data matches one."],"exampleFix":"// before\nMedia media = new Media(MimeTypeUtils.parseMimeType(\"video/mp4\"), someUrlObject); // getData() class unsupported\n// after\nbyte[] videoBytes = someUrlObject.openStream().readAllBytes();\nMedia media = new Media(MimeTypeUtils.parseMimeType(\"video/mp4\"), videoBytes);","handlingStrategy":"validation","validationCode":"static void assertVideoMediaSupported(Media media) {\n    Object data = media.getData();\n    if (!(data instanceof byte[]) && !(data instanceof Resource)) {\n        throw new IllegalArgumentException(\"Video media data must be byte[] or Resource, got: \"\n            + (data == null ? \"null\" : data.getClass()));\n    }\n}","typeGuard":"static Optional<byte[]> asVideoBytes(Media media) {\n    Object d = media.getData();\n    if (d instanceof byte[] b) return Optional.of(b);\n    if (d instanceof Resource r) {\n        try { return Optional.of(r.getInputStream().readAllBytes()); }\n        catch (IOException e) { return Optional.empty(); }\n    }\n    return Optional.empty();\n}","tryCatchPattern":"try {\n    return bedrockModel.call(prompt);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Invalid video content type\")) {\n        log.error(\"Rebuild video media with byte[]/Resource data: {}\", e.getMessage());\n    }\n    throw e;\n}","preventionTips":["Always pass video content as byte[] or Resource with an explicit video/* MIME type.","Download remote video URLs to bytes before constructing Media.","Use only Bedrock-supported video formats (mp4, mov, mkv, webm)."],"tags":["bedrock","media","argument-validation"],"backgroundTag":"incompatible-source-type","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"}