{"record":{"id":"270abab036be2e40","repo":"spring-projects/spring-ai","slug":"java-io-ioexception-270aba","errorCode":null,"errorMessage":"java.io.IOException","messagePattern":"java\\.io\\.IOException","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/DefaultChatClient.java","lineNumber":204,"sourceCode":"\t\t\treturn this;\n\t\t}\n\n\t\t@Override\n\t\tpublic PromptUserSpec text(String text) {\n\t\t\tAssert.hasText(text, \"text cannot be null or empty\");\n\t\t\tthis.text = text;\n\t\t\treturn this;\n\t\t}\n\n\t\t@Override\n\t\tpublic PromptUserSpec text(Resource text, Charset charset) {\n\t\t\tAssert.notNull(text, \"text cannot be null\");\n\t\t\tAssert.notNull(charset, \"charset cannot be null\");\n\t\t\ttry {\n\t\t\t\tthis.text(text.getContentAsString(charset));\n\t\t\t}\n\t\t\tcatch (IOException e) {\n\t\t\t\tthrow new RuntimeException(e);\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\t@Override\n\t\tpublic PromptUserSpec text(Resource text) {\n\t\t\tAssert.notNull(text, \"text cannot be null\");\n\t\t\tthis.text(text, Charset.defaultCharset());\n\t\t\treturn this;\n\t\t}\n\n\t\t@Override\n\t\tpublic PromptUserSpec param(String key, Object value) {\n\t\t\tAssert.hasText(key, \"key cannot be null or empty\");\n\t\t\tAssert.notNull(value, \"value cannot be null\");\n\t\t\tthis.params.put(key, value);\n\t\t\treturn this;\n\t\t}","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/DefaultChatClient.java#L186-L222","documentation":"PromptUserSpec.text(Resource, Charset) reads the Resource content via getContentAsString, which can throw IOException; the client wraps it in a RuntimeException. It indicates the underlying resource (file, classpath entry, URL resource) could not be read.","triggerScenarios":"Calling .user(u -> u.text(resource, charset)) where the Resource points to a missing file, unreadable location, or a stream that fails mid-read (e.g. FileSystemResource on a non-existent path, ClassPathResource not on the classpath).","commonSituations":"Typo'd classpath prompt file; file deleted or path relative to wrong working directory; permissions issue on a mounted volume; encoding mismatch causing read failure.","solutions":["Verify the resource exists (resource.exists()) and is readable before passing it","Check the classpath (src/main/resources) or absolute file path correctness","Read the content yourself with proper error handling and pass the String via text(String)","Catch the RuntimeException and inspect the IOException cause for the real path/message"],"exampleFix":"// before\n.user(u -> u.text(new FileSystemResource(\"prompts/user.txt\"), StandardCharsets.UTF_8)); // missing file\n// after\nResource res = new FileSystemResource(\"prompts/user.txt\");\nif (res.exists()) {\n    .user(u -> u.text(res, StandardCharsets.UTF_8));\n} else {\n    throw new IllegalStateException(\"Prompt resource missing: \" + res.getFilename());\n}","handlingStrategy":"validation","validationCode":"Resource r = new ClassPathResource(\"prompts/user.txt\"); if (!r.exists() || !r.isReadable()) throw new IllegalStateException(\"User prompt resource missing/unreadable\");","typeGuard":"static String safeText(Resource r, Charset cs) { try { return r.getContentAsString(cs); } catch (IOException e) { return null; } }","tryCatchPattern":"try { builder.user(u -> u.text(res, charset)); } catch (RuntimeException e) { if (e.getCause() instanceof IOException io) { throw new IllegalStateException(\"Cannot read user prompt: \" + io.getMessage(), io); } throw e; }","preventionTips":["Check resource.exists()/isReadable() before passing to the builder","Read resources yourself and pass Strings for explicit error handling","Ensure prompt files are packaged in the artifact and present in the working directory"],"tags":["java","chat-client","io","resource"],"backgroundTag":"file-read-failed","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}