spring-projects/spring-ai · error · java.lang.IllegalArgumentException
Cannot safely convert numeric value '{value}' to int
Error message
Cannot safely convert numeric value '{value}' to int What it means
When binding prompt arguments to an int/Integer parameter, convertArgumentValue delegates to toIntegerExact, which converts the Number via BigDecimal.intValueExact(). If the value is fractional, out of int range, or unrepresentable, intValueExact throws ArithmeticException (or NumberFormatException), rethrown as this IllegalArgumentException. The library refuses lossy conversions rather than silently truncating.
Source
Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/prompt/AbstractMcpPromptMethodCallback.java:338
else if (targetType == Boolean.class || targetType == boolean.class) {
if (value instanceof Boolean) {
return value;
}
else {
return Boolean.parseBoolean(value.toString());
}
}
// For other types, return as is and hope for the best
return value;
}
private int toIntegerExact(Number value) {
try {
return this.toBigDecimal(value).intValueExact();
}
catch (ArithmeticException | NumberFormatException ex) {
throw new IllegalArgumentException("Cannot safely convert numeric value '" + value + "' to int", ex);
}
}
private long toLongExact(Number value) {
try {
return this.toBigDecimal(value).longValueExact();
}
catch (ArithmeticException | NumberFormatException ex) {
throw new IllegalArgumentException("Cannot safely convert numeric value '" + value + "' to long", ex);
}
}
private BigDecimal toBigDecimal(Number value) {
if (value instanceof BigDecimal bigDecimal) {
return bigDecimal;
}
if (value instanceof BigInteger bigInteger) {
return new BigDecimal(bigInteger);View on GitHub (pinned to 98a7beda4f)
Solutions
- Change the parameter type to long or double if the value can legitimately be larger or fractional.
- Validate/coerce the incoming argument client-side (or in a wrapper method) before it reaches the handler.
- Catch IllegalArgumentException around the callback invocation and return a descriptive MCP error to the client asking for an integer in range.
Example fix
// before @McpArg int maxResults // after @McpArg long maxResults // or validate: if (d != Math.floor(d) || d > Integer.MAX_VALUE) throw ...
Defensive patterns
Strategy: try-catch
Validate before calling
boolean safeAsInt(Number n) {
try { return new BigDecimal(n.toString()).intValueExact() >= 0; }
catch (ArithmeticException | NumberFormatException e) { return false; }
} Type guard
boolean isExactInt(Object v) {
return v instanceof Number n
&& new BigDecimal(n.toString()).scale() <= 0
&& new BigDecimal(n.toString()).compareTo(BigDecimal.valueOf(Integer.MAX_VALUE)) <= 0
&& new BigDecimal(n.toString()).compareTo(BigDecimal.valueOf(Integer.MIN_VALUE)) >= 0;
} Try / catch
try {
Object result = callback.apply(exchange, request);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Cannot safely convert numeric value")) {
return errorResponse("Argument must be an integer within int range");
}
throw e;
} Prevention
- Type numeric prompt arguments as long or double when range/fraction is possible.
- Document expected ranges in the prompt description so LLM clients send valid integers.
- Validate arguments in the handler before arithmetic use.
When it happens
Trigger: A client sends a prompt argument like 3.5, 1e30, or 2147483648 for a method parameter typed int/Integer with @McpArg; buildArgs -> convertArgumentValue -> toIntegerExact throws at invocation time.
Common situations: LLM clients emitting float-typed numbers for integer fields (JSON 3.0 vs 3); client sending a count/limit exceeding Integer.MAX_VALUE; decimal input like 0.5 for an int parameter.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Cannot safely convert numeric value '{value}' to long
- Failed to assign all URI variables to method parameters. Ass
- Failed to read stdio connection resource
- SSE connection '<connectionName>' requires a 'url' property.
- Failed to create SSE transport for connection '<connectionNa
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/4552cc7a05e6f6a1.
Report an issue: GitHub.