alibaba/spring-ai-alibaba · error · IllegalArgumentException
maxCachedThreads must be greater than or equal to 0
Error message
maxCachedThreads must be greater than or equal to 0
What it means
Builder.maxCachedThreads(int) validates its argument and throws IllegalArgumentException if a negative value is passed. The cache of thread states can be disabled with 0, but any negative count is invalid.
Source
Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/savers/mysql/MysqlSaver.java:600
/**
* A builder for MysqlSaver.
*/
public static class Builder {
private DataSource dataSource;
private CreateOption createOption = CreateOption.CREATE_IF_NOT_EXISTS;
private StateSerializer stateSerializer;
private int maxCachedThreads = 1024;
/**
* Sets the maximum number of latest checkpoints retained in memory.
*
* @param maxCachedThreads max cached threads, or 0 to disable the cache
* @return this builder
*/
public Builder maxCachedThreads(int maxCachedThreads) {
if (maxCachedThreads < 0) {
throw new IllegalArgumentException("maxCachedThreads must be greater than or equal to 0");
}
this.maxCachedThreads = maxCachedThreads;
return this;
}
/**
* Sets the state serializer
*
* @param stateSerializer the state serializer
* @return this builder
*/
public Builder stateSerializer(StateSerializer stateSerializer) {
this.stateSerializer = stateSerializer;
return this;
}
/**
* Sets the datasourceView on GitHub (pinned to f82da0b50f)
Solutions
- Pass a non-negative integer; use 0 to disable the thread cache entirely.
- Clamp or validate externally supplied config values before passing them to the builder.
- Map a '-1 means unlimited' convention to a large positive number or to 0 explicitly before building.
Example fix
// before
int threads = Integer.parseInt(env.getProperty("cache.threads")); // -1 = unlimited convention
MysqlSaver.builder().maxCachedThreads(threads); // IllegalArgumentException
// after
int threads = Math.max(0, Integer.parseInt(env.getProperty("cache.threads", "0")));
MysqlSaver.builder().maxCachedThreads(threads); Defensive patterns
Strategy: validation
Validate before calling
int t = config.maxCachedThreads(); if (t < 0) t = 0; // or map your '-1 = unlimited' convention explicitly builder.maxCachedThreads(t);
Prevention
- Never feed builder methods raw external config without clamping.
- Remember 0 disables the cache; negative values are always rejected.
- Add unit tests for config-to-builder value mapping.
When it happens
Trigger: Calling MysqlSaver.builder().maxCachedThreads(-1) (or computing the value from a config/property that resolves negative, e.g. an int parsed from a bad environment variable) before build().
Common situations: Feeding maxCachedThreads from external configuration where a sentinel like -1 meant 'unlimited' in the developer's own config convention; arithmetic producing a negative value; typos in config keys shifting values.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- At least one fallback model must be specified
- maxAttempts must be greater than or equal to 1
- initialDelay must be greater than or equal to 0.
- maxContentLength must be positive
- maxCachedThreads must be greater than or equal to 0
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/f8a796981b6fac94.
Report an issue: GitHub.