spring-projects/spring-ai · warning
Failed to render resource
Error message
Failed to render resource: ${resource.getDescription()} What it means
PromptTemplate.renderResource loads template content from a Spring Resource. If reading the resource throws IOException, the template logs a warning including the resource description and falls back to the placeholder string "[Unable to render resource: ...]" instead of propagating the exception — so the failure shows up later as odd template text rather than an error at render time.
Solutions
- Verify the resource path and that the file exists/is on the classpath at runtime (e.g. Resource.exists())
- Check file permissions and packaging (resource included in the jar, correct resources directory)
- Read the returned string and detect the "[Unable to render resource:" sentinel to fail fast in your code
- Pre-load the template content yourself (Files.readString) and pass the raw string to PromptTemplate
Example fix
// before
PromptTemplate t = new PromptTemplate(resource); // silently yields [Unable to render resource: ...]
// after
if (!resource.exists()) {
throw new IllegalStateException("Template resource missing: " + resource.getDescription());
}
PromptTemplate t = new PromptTemplate(resource.getContentAsString(StandardCharsets.UTF_8)); Defensive patterns
Strategy: try-catch
Validate before calling
if (!resource.exists() || !resource.isReadable()) {
throw new IllegalStateException("Template resource unreadable: " + resource.getDescription());
} Try / catch
try {
String content = resource.getContentAsString(StandardCharsets.UTF_8);
} catch (IOException e) {
// template content unavailable; fail fast instead of letting PromptTemplate emit the sentinel
} Prevention
- Check resource.exists() before constructing PromptTemplate
- Verify resources are packaged in the jar
- Prefer loading template strings explicitly over Resource-based templates in containers
- Scan rendered prompts for the "[Unable to render resource:" sentinel in tests
When it happens
Trigger: Creating/using a PromptTemplate backed by a Resource (classpath or file) whose content cannot be read: missing file, unreadable permissions, broken InputStream, or IO error during getContentAsString.
Common situations: classpath: resource not on the classpath after packaging; file: path wrong or moved; resource inside a jar not loaded correctly; permissions issues in containers.
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 read 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/f0fd9f891de630fd.
Report an issue: GitHub.
Appendix: source
Thrown at spring-ai-model/src/main/java/org/springframework/ai/chat/prompt/PromptTemplate.java:165
if (resource == null) {
return "";
}
try {
// Handle ByteArrayResource specially
if (resource instanceof ByteArrayResource byteArrayResource) {
return new String(byteArrayResource.getByteArray(), StandardCharsets.UTF_8);
}
// If the resource exists but is empty
if (!resource.exists() || resource.contentLength() == 0) {
return "";
}
// For other Resource types or as fallback
return resource.getContentAsString(StandardCharsets.UTF_8);
}
catch (IOException e) {
if (log.isWarnEnabled()) {
log.warn("Failed to render resource: " + resource.getDescription(), e);
}
return "[Unable to render resource: " + resource.getDescription() + "]";
}
}
// From PromptTemplateMessageActions.
@Override
public Message createMessage() {
return new UserMessage(render());
}
@Override
public Message createMessage(List<Media> mediaList) {
return UserMessage.builder().text(render()).media(mediaList).build();
}
@OverrideView on GitHub (pinned to 98a7beda4f)