alibaba/spring-ai-alibaba · error · IllegalArgumentException
port must be greater than 0
Error message
port must be greater than 0
What it means
PostgresSaver.Builder.build() requires a positive port when no external DataSource was supplied, since it constructs a PGSimpleDataSource itself. A null or non-positive port throws this IllegalArgumentException before any connection is attempted.
Source
Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/savers/postgresql/PostgresSaver.java:741
}
private String requireNotBlank(String value, String name) {
if (requireNonNull(value, format("'%s' cannot be null", name)).isBlank()) {
throw new IllegalArgumentException(format("'%s' cannot be blank", name));
}
return value;
}
public PostgresSaver build() {
if (stateSerializer == null) {
log.info("No StateSerializer for saver provided, using default SpringAiJacksonStateSerializer, please make sure saver uses the same serializer of the graph.");
this.stateSerializer = StateGraph.DEFAULT_JACKSON_SERIALIZER;
}
// If datasource is already set (e.g., for testing), use it directly
if (datasource == null) {
if (port == null || port <= 0) {
throw new IllegalArgumentException("port must be greater than 0");
}
var ds = new PGSimpleDataSource();
ds.setDatabaseName(requireNotBlank(database, "database"));
ds.setUser(requireNotBlank(user, "user"));
ds.setPassword(requireNonNull(password, "password cannot be null"));
ds.setPortNumbers(new int[] {port});
ds.setServerNames(new String[] {requireNotBlank(host, "host")});
datasource = ds;
}
try {
return new PostgresSaver(this);
}
catch (SQLException e) {
throw new RuntimeException(e);
}
}
}View on GitHub (pinned to f82da0b50f)
Solutions
- Set a valid port, e.g. builder.port(5432) for default Postgres.
- Or inject your own DataSource via builder.datasource(...) to bypass port validation (useful in tests).
- Fix the config source so the port property resolves to a positive integer.
Example fix
// before PostgresSaver.builder().host(host).database(db).user(u).password(p).build(); // after PostgresSaver.builder().host(host).port(5432).database(db).user(u).password(p).build();
Defensive patterns
Strategy: validation
Validate before calling
if (dataSource == null && (port == null || port <= 0)) {
throw new IllegalStateException("Provide port(...) > 0 or a DataSource");
} Try / catch
try { return builder.build(); } catch (IllegalArgumentException e) { if (e.getMessage().contains("port")) builder.port(5432); return builder.build(); } Prevention
- Always set port when not supplying a DataSource
- Default to 5432 for standard Postgres
- Parse port config with validation, not raw Integer.parseInt
When it happens
Trigger: Building a saver without setting datasource(...) and without port(...) or with port(0)/port(-5432) — commonly when the port config property is missing or parsed as 0.
Common situations: Missing DB_PORT env var defaulted to 0; tests that set a DataSource don't hit this, so it surfaces only in production wiring; port mapping mistakes in Docker Compose.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- '%s' cannot be blank
- SkillRegistry must be provided. Use FileSystemSkillRegistry.
- At least one limit must be specified (threadLimit or runLimi
- maxCachedThreads must be greater than or equal to 0
- oss ak or sk should be set.
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/6a6fa00eb8db165a.
Report an issue: GitHub.