spring-projects/spring-ai · error · RuntimeException
Failed to read resource
Error message
Failed to read resource
What it means
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.
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.
Example fix
// before
new PromptTemplate(new FileSystemResource("prompts/system.txt"));
// after
Resource res = new ClassPathResource("prompts/system.txt");
if (!res.exists()) throw new IllegalStateException("template missing");
new PromptTemplate(res); Defensive patterns
Strategy: validation
Validate before calling
Resource r = new ClassPathResource("prompts/system.txt"); if (!r.exists() || !r.isReadable()) throw new IllegalStateException("template resource missing/unreadable: " + r); Try / catch
try { return new PromptTemplate(resource); } catch (RuntimeException e) { logger.error("template resource unreadable", e); return new PromptTemplate("fallback template"); } Prevention
- 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
When it happens
Trigger: new PromptTemplate(Resource, variables, renderer) where the Resource points to a missing file, an unreadable location, or an IO error occurs mid-read.
Common situations: 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.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Failed to render resource
- Failed to cache the resource:
- Failed to read resource:
- Failed to read resource
- IOException (wrapped RuntimeException)
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/7c872de3dcec9529.
Report an issue: GitHub.
Appendix: source
Thrown at spring-ai-model/src/main/java/org/springframework/ai/chat/prompt/PromptTemplate.java:94
Assert.notNull(renderer, "renderer cannot be null");
this.template = template;
this.variables.putAll(variables);
this.renderer = renderer;
}
PromptTemplate(Resource resource, Map<String, Object> variables, TemplateRenderer renderer) {
Assert.notNull(resource, "resource cannot be null");
Assert.notNull(variables, "variables cannot be null");
Assert.noNullElements(variables.keySet(), "variables keys cannot be null");
Assert.notNull(renderer, "renderer cannot be null");
try (InputStream inputStream = resource.getInputStream()) {
this.template = StreamUtils.copyToString(inputStream, Charset.defaultCharset());
Assert.hasText(this.template, "template cannot be null or empty");
}
catch (IOException ex) {
throw new RuntimeException("Failed to read resource", ex);
}
this.variables.putAll(variables);
this.renderer = renderer;
}
public void add(String name, Object value) {
this.variables.put(name, value);
}
public String getTemplate() {
return this.template;
}
// From PromptTemplateStringActions.
@Override
public String render() {
// Process internal variables to handle Resources before renderingView on GitHub (pinned to 98a7beda4f)