alibaba/spring-ai-alibaba · error · IllegalArgumentException
targetFolder '%s' must be a directory
Error message
targetFolder '%s' must be a directory
What it means
FileSystemSaver persists checkpoints to a folder. During construction it verifies that the configured targetFolder either does not exist or is a directory; if the path exists as a regular file, IllegalArgumentException is thrown with the path in the message.
Source
Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/savers/file/FileSystemSaver.java:100
.stateSerializer(stateSerializer));
}
@SuppressWarnings("unchecked")
protected FileSystemSaver(Builder builder) {
StateSerializer stateSerializer = builder.stateSerializer;
if (stateSerializer == null) {
this.serializer = new CheckPointSerializer(StateGraph.DEFAULT_JACKSON_SERIALIZER);
}
else {
this.serializer = new CheckPointSerializer(stateSerializer);
}
this.targetFolder = Objects.requireNonNull(builder.targetFolder, "targetFolder cannot be null");
this.maxCachedThreads = builder.maxCachedThreads;
this.latestCheckpointCache = createLatestCheckpointCache(builder.maxCachedThreads);
try {
if (Files.exists(this.targetFolder) && !Files.isDirectory(this.targetFolder)) {
throw new IllegalArgumentException(format("targetFolder '%s' must be a directory", this.targetFolder));
}
Files.createDirectories(this.targetFolder);
}
catch (IOException ex) {
throw new IllegalArgumentException(format("targetFolder '%s' cannot be created", this.targetFolder), ex);
}
}
/**
* Creates a new builder for FileSystemSaver.
* @return a new Builder instance
*/
public static Builder builder() {
return new Builder();
}
private String getBaseName(RunnableConfig config) {View on GitHub (pinned to f82da0b50f)
Solutions
- Point targetFolder at a directory (existing or to-be-created), not a file
- Delete or move the file occupying the path
- Choose a different checkpoint directory
Example fix
// before
FileSystemSaver.builder().targetFolder(Path.of("/data/checkpoints.db")).build();
// after
FileSystemSaver.builder().targetFolder(Path.of("/data/checkpoints")).build(); Defensive patterns
Strategy: validation
Validate before calling
if (Files.exists(targetFolder) && !Files.isDirectory(targetFolder)) throw new IllegalArgumentException("not a directory: " + targetFolder); Type guard
boolean usableFolder(Path p) { return !Files.exists(p) || Files.isDirectory(p); } Try / catch
try { FileSystemSaver.builder().targetFolder(p).build(); } catch (IllegalArgumentException e) { /* pick another folder */ } Prevention
- Always configure a directory path, never a file
- Pre-create the directory at deployment time
- Check for stray files at the configured path
When it happens
Trigger: new FileSystemSaver.Builder().targetFolder(Path.of("/some/file.txt")) where that path already exists as a plain file, then build().
Common situations: Pointing the saver at a file (e.g. a config file or database file) instead of a directory, or a leftover file occupying the intended checkpoint directory path.
Related errors
- maxCachedThreads must be greater than or equal to 0
- targetFolder '%s' cannot be created
- maxCachedThreads must be greater than or equal to 0
- INVALID_PARAMS
- Oauth2UserNotFound
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/0a53f46ec0566ca6.
Report an issue: GitHub.