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

  1. Point targetFolder at a directory (existing or to-be-created), not a file
  2. Delete or move the file occupying the path
  3. 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

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


AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/0a53f46ec0566ca6. Report an issue: GitHub.