alibaba/spring-ai-alibaba · error · IllegalArgumentException

maxRetries must be non-negative

Error message

maxRetries must be non-negative

What it means

Builder.maxRetries validates that the retry count is non-negative; a negative value throws IllegalArgumentException. maxRetries is added to 1 to form the total attempt count, so negative values would produce zero or nonsensical attempt budgets (and a broken 'Failed after N attempts' message).

Source

Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/tools/WebFetchTool.java:449

		public Builder maxContentLength(int maxContentLength) {
			if (maxContentLength <= 0) {
				throw new IllegalArgumentException("maxContentLength must be positive");
			}
			this.maxContentLength = maxContentLength;
			return this;
		}

		public Builder maxCacheSize(int maxCacheSize) {
			if (maxCacheSize <= 0) {
				throw new IllegalArgumentException("maxCacheSize must be positive");
			}
			this.maxCacheSize = maxCacheSize;
			return this;
		}

		public Builder maxRetries(int maxRetries) {
			if (maxRetries < 0) {
				throw new IllegalArgumentException("maxRetries must be non-negative");
			}
			this.maxRetries = maxRetries;
			return this;
		}

		public Builder withName(String name) {
			this.name = name;
			return this;
		}

		public Builder withDescription(String description) {
			this.description = description;
			return this;
		}

		public ToolCallback build() {
			return FunctionToolCallback.builder(this.name, buildWebFetchTool())
				.description(this.description)

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Pass 0 or a positive integer — 0 means a single attempt with no retries.
  2. If loading from config, default missing values to 0 and reject negatives before building.
  3. Omit the call to keep the default retry policy.
  4. Clamp with Math.max(0, configuredValue) for dynamic values.

Example fix

// before
.maxRetries(-1)
// after
.maxRetries(2)
Defensive patterns

Strategy: validation

Validate before calling

int retries = properties.maxRetries();
if (retries < 0) {
    throw new IllegalArgumentException("webfetch.max-retries must be >= 0, got " + retries);
}

Type guard

boolean isValidRetryCount(int v) { return v >= 0; }

Try / catch

try {
    builder.maxRetries(retries);
} catch (IllegalArgumentException e) {
    log.warn("invalid maxRetries {}, falling back to 0", retries);
    builder.maxRetries(0);
}

Prevention

When it happens

Trigger: Calling .maxRetries(-1) or any negative number on the WebFetchTool Builder, typically from a misparsed config value.

Common situations: Config property that defaults to -1 when absent; subtracting from a counter that can go below zero; typo in a properties file (maxRetries=-1 meant as 'disable').

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


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