{"record":{"id":"7c872de3dcec9529","repo":"spring-projects/spring-ai","slug":"failed-to-read-resource-7c872d","errorCode":null,"errorMessage":"Failed to read resource","messagePattern":"Failed to read resource","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"spring-ai-model/src/main/java/org/springframework/ai/chat/prompt/PromptTemplate.java","lineNumber":94,"sourceCode":"\t\tAssert.notNull(renderer, \"renderer cannot be null\");\n\n\t\tthis.template = template;\n\t\tthis.variables.putAll(variables);\n\t\tthis.renderer = renderer;\n\t}\n\n\tPromptTemplate(Resource resource, Map<String, Object> variables, TemplateRenderer renderer) {\n\t\tAssert.notNull(resource, \"resource cannot be null\");\n\t\tAssert.notNull(variables, \"variables cannot be null\");\n\t\tAssert.noNullElements(variables.keySet(), \"variables keys cannot be null\");\n\t\tAssert.notNull(renderer, \"renderer cannot be null\");\n\n\t\ttry (InputStream inputStream = resource.getInputStream()) {\n\t\t\tthis.template = StreamUtils.copyToString(inputStream, Charset.defaultCharset());\n\t\t\tAssert.hasText(this.template, \"template cannot be null or empty\");\n\t\t}\n\t\tcatch (IOException ex) {\n\t\t\tthrow new RuntimeException(\"Failed to read resource\", ex);\n\t\t}\n\t\tthis.variables.putAll(variables);\n\t\tthis.renderer = renderer;\n\t}\n\n\tpublic void add(String name, Object value) {\n\t\tthis.variables.put(name, value);\n\t}\n\n\tpublic String getTemplate() {\n\t\treturn this.template;\n\t}\n\n\t// From PromptTemplateStringActions.\n\n\t@Override\n\tpublic String render() {\n\t\t// Process internal variables to handle Resources before rendering","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/spring-ai-model/src/main/java/org/springframework/ai/chat/prompt/PromptTemplate.java#L76-L112","documentation":"PromptTemplate's Resource-based constructor reads the template text from the Spring Resource with StreamUtils.copyToString and wraps any IOException in a RuntimeException('Failed to read resource'). It also asserts the resulting template text is non-empty. The error means the underlying template file could not be opened or read.","triggerScenarios":"new PromptTemplate(Resource, variables, renderer) where the Resource points to a missing file, an unreadable location, or an IO error occurs mid-read.","commonSituations":"Wrong classpath path (classpath:templates/prompt.txt misspelled or file not under src/main/resources), file outside the packaged JAR, missing read permissions, or an empty template file.","solutions":["Verify the resource path exists and is on the classpath (e.g. src/main/resources) and the Resource resolves via resource.exists().","Check file permissions and that the file is included in the build artifact (JAR).","Ensure the file is non-empty; the constructor asserts hasText on the template.","Catch RuntimeException around construction and fall back to an inline template string."],"exampleFix":"// before\nnew PromptTemplate(new FileSystemResource(\"prompts/system.txt\"));\n// after\nResource res = new ClassPathResource(\"prompts/system.txt\");\nif (!res.exists()) throw new IllegalStateException(\"template missing\");\nnew PromptTemplate(res);","handlingStrategy":"validation","validationCode":"Resource r = new ClassPathResource(\"prompts/system.txt\"); if (!r.exists() || !r.isReadable()) throw new IllegalStateException(\"template resource missing/unreadable: \" + r);","typeGuard":null,"tryCatchPattern":"try { return new PromptTemplate(resource); } catch (RuntimeException e) { logger.error(\"template resource unreadable\", e); return new PromptTemplate(\"fallback template\"); }","preventionTips":["Verify resource paths exist under src/main/resources and are packaged into the JAR","Call resource.exists()/getInputStream() in a smoke test at startup","Check file read permissions in containerized deployments","Keep template strings as an inline fallback for critical prompts"],"tags":["io","resource","template"],"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-23T08:17:48.524Z"}