{"record":{"id":"2c1981c180b8a4ec","repo":"alibaba/spring-ai-alibaba","slug":"failed-to-read-resource","errorCode":null,"errorMessage":"Failed to read resource","messagePattern":"Failed to read resource","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/tool/multimodal/MultimodalToolCallResultConverter.java","lineNumber":146,"sourceCode":"\t\t}\n\t\telse if (data instanceof URL url) {\n\t\t\ttry {\n\t\t\t\tputUriOrEncodeToDataUrl(url.toURI(), mimeTypeStr, itemMap);\n\t\t\t}\n\t\t\tcatch (java.net.URISyntaxException ex) {\n\t\t\t\tputUriOrEncodeToDataUrl(URI.create(url.toExternalForm()), mimeTypeStr, itemMap);\n\t\t\t}\n\t\t}\n\t\telse if (data instanceof String s && isUriLike(s)) {\n\t\t\tputUriOrEncodeToDataUrl(URI.create(s), mimeTypeStr, itemMap);\n\t\t}\n\t\telse if (data instanceof Resource resource) {\n\t\t\thandleBytes(() -> {\n\t\t\t\ttry {\n\t\t\t\t\treturn resource.getContentAsByteArray();\n\t\t\t\t}\n\t\t\t\tcatch (IOException e) {\n\t\t\t\t\tthrow new RuntimeException(\"Failed to read resource\", e);\n\t\t\t\t}\n\t\t\t}, mimeTypeStr, itemMap);\n\t\t}\n\t\telse if (data != null) {\n\t\t\ttry {\n\t\t\t\tbyte[] bytes = media.getDataAsByteArray();\n\t\t\t\tif (bytes != null && bytes.length > 0) {\n\t\t\t\t\thandleBytes(() -> bytes, mimeTypeStr, itemMap);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (IllegalStateException e) {\n\t\t\t\tString s = data.toString();\n\t\t\t\tif (isUriLike(s)) {\n\t\t\t\t\tputUriOrEncodeToDataUrl(URI.create(s), mimeTypeStr, itemMap);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn itemMap;","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/tool/multimodal/MultimodalToolCallResultConverter.java#L128-L164","documentation":"In MultimodalToolCallResultConverter.mediaToMap(), when media data is a Spring Resource, its content is read via getContentAsByteArray(); an IOException there is rethrown as RuntimeException \"Failed to read resource\". It means the binary content backing the resource could not be loaded.","triggerScenarios":"Passing a Resource (e.g. UrlResource, ClassPathResource, FileSystemResource) whose backing file/stream is missing, unreadable, or whose URL connection fails during conversion of a ToolMultimodalResult.","commonSituations":"Deleted or moved temp files referenced by URL resources, classpath resources packaged incorrectly, expired remote URLs, permission issues on file resources.","solutions":["Verify the resource location exists and is readable before returning it from the tool.","Prefer passing raw byte[]/Media instead of a lazily-resolved Resource when the source may vanish.","Check that classpath resources are on the classpath at runtime (jar packaging includes them).","Catch this RuntimeException and map to a tool error message for the model."],"exampleFix":"// before\nreturn new UrlResource(\"file:///tmp/gone.png\");\n// after\nResource r = new UrlResource(\"file:///tmp/gone.png\");\nif (!r.exists()) { throw new IllegalStateException(\"media file missing: \" + r); }\nreturn r;","handlingStrategy":"validation","validationCode":"if (r instanceof Resource res && !res.exists()) { throw new IllegalStateException(\"missing resource: \" + res); }","typeGuard":"if (data instanceof Resource res && res.exists() && res.isReadable()) { /* safe to convert */ }","tryCatchPattern":"try { converter.convert(result, returnType); } catch (RuntimeException e) { if (e.getMessage().startsWith(\"Failed to read resource\")) { /* return tool error to model */ } }","preventionTips":["Check Resource.exists()/isReadable() before returning from tools","Prefer in-memory byte[]/Media over lazy Resources","Ensure classpath resources are packaged in the jar","Clean up temp media files only after conversion"],"tags":["io","resource","multimodal","file-read"],"backgroundTag":"file-read-failed","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}