{"record":{"id":"5f5d5d2e126ca1cc","repo":"spring-projects/spring-ai","slug":"media-data-is-not-a-byte","errorCode":null,"errorMessage":"Media data is not a byte[]","messagePattern":"Media data is not a byte\\[\\]","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spring-ai-commons/src/main/java/org/springframework/ai/content/Media.java","lineNumber":193,"sourceCode":"\t/**\n\t * Get the media data object.\n\t * @return a {@link String} (URI/URL/base64), a {@code byte[]}, or a\n\t * {@link java.net.URL}\n\t */\n\tpublic Object getData() {\n\t\treturn this.data;\n\t}\n\n\t/**\n\t * Get the media data as a byte array\n\t * @return the media data as a byte array\n\t */\n\tpublic byte[] getDataAsByteArray() {\n\t\tif (this.data instanceof byte[]) {\n\t\t\treturn (byte[]) this.data;\n\t\t}\n\t\telse {\n\t\t\tthrow new IllegalStateException(\"Media data is not a byte[]\");\n\t\t}\n\t}\n\n\t/**\n\t * Get the media id\n\t * @return the media id\n\t */\n\tpublic @Nullable String getId() {\n\t\treturn this.id;\n\t}\n\n\t/**\n\t * Get the media name.\n\t * @return the media name\n\t */\n\tpublic String getName() {\n\t\treturn this.name;\n\t}","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/spring-ai-commons/src/main/java/org/springframework/ai/content/Media.java#L175-L211","documentation":"getDataAsByteArray() returns the stored media payload as a byte array, but Media can hold other data types (e.g. Resource, URL-derived objects). If the internal data field is not a byte[], the method throws IllegalStateException instead of converting.","triggerScenarios":"Calling media.getDataAsByteArray() on a Media instance constructed via a constructor or builder path that stored a non-byte[] payload (URL, Resource-backed object) rather than raw bytes.","commonSituations":"Persisting/restoring chat memory with media created from URLs, then assuming the in-memory representation is raw bytes; calling the accessor defensively after deserialization.","solutions":["Ensure the Media was built with byte[] data before calling getDataAsByteArray()","If data may be another type, obtain bytes via the builder/data(Resource) path or convert yourself","Catch IllegalStateException and fall back to a conversion path","For empty/null media, guard before calling (the method does not null-check semantics beyond instanceof)"],"exampleFix":"// before\nbyte[] bytes = media.getDataAsByteArray(); // IllegalStateException for non-byte[] data\n// after\nif (media.getData() instanceof byte[] bytes) {\n    use(bytes);\n} else {\n    use(convertToBytes(media.getData()));\n}","handlingStrategy":"type-guard","validationCode":"if (media.getData() instanceof byte[] b && b.length > 0) { /* safe */ }","typeGuard":"static byte[] safeBytes(Media m) {\n    return m.getData() instanceof byte[] b ? b : null;\n}","tryCatchPattern":"try {\n    byte[] b = media.getDataAsByteArray();\n} catch (IllegalStateException e) {\n    byte[] b = convert(media.getData());\n}","preventionTips":["Always construct Media with byte[] payloads when you later need raw bytes","Centralize media creation in one factory","Document the in-memory data type per construction path"],"tags":["state","media","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}