spring-projects/spring-ai · error · java.lang.IllegalArgumentException
Cannot safely convert numeric value '{value}' to long
Error message
Cannot safely convert numeric value '{value}' to long What it means
Analogous to the int case: converting a prompt argument to long/Long uses toLongExact, which calls BigDecimal.longValueExact() and rethrows ArithmeticException/NumberFormatException as this IllegalArgumentException when the numeric value is fractional or exceeds Long range. The framework avoids silent truncation/overflow of client-supplied numbers.
Source
Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/prompt/AbstractMcpPromptMethodCallback.java:347
// 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);
}
if (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long) {
return BigDecimal.valueOf(value.longValue());
}
if (value instanceof Float || value instanceof Double) {
// Use the exact binary floating-point value. The shorter toString()
// representation may denote a different integer near large boundaries.
return new BigDecimal(value.doubleValue());
}View on GitHub (pinned to 98a7beda4f)
Solutions
- Use double, BigDecimal, or String parameter types for values that may exceed long range or be fractional.
- Have the client send an integer literal within [-2^63, 2^63-1].
- Catch the IllegalArgumentException in the callback layer and map it to an MCP tool/prompt error response.
Example fix
// before @McpArg long fileSize // client sends 1.5e19 // after @McpArg double fileSize // or accept String and parse with validation
Defensive patterns
Strategy: try-catch
Validate before calling
boolean safeAsLong(Number n) {
try { return new BigDecimal(n.toString()).longValueExact() >= 0; }
catch (ArithmeticException | NumberFormatException e) { return false; }
} Type guard
boolean isExactLong(Object v) {
return v instanceof Number n
&& new BigDecimal(n.toString()).scale() <= 0
&& new BigDecimal(n.toString()).compareTo(BigDecimal.valueOf(Long.MAX_VALUE)) <= 0
&& new BigDecimal(n.toString()).compareTo(BigDecimal.valueOf(Long.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 long range");
}
throw e;
} Prevention
- Use double or String types for values that may exceed 2^63-1 (e.g. large IDs, sizes).
- Instruct clients via prompt documentation to send bounded integer literals.
- Prefer Long over long so nulls from missing arguments are distinguishable.
When it happens
Trigger: A prompt argument such as 1.5 or 18446744073709551616 (2^64) bound to a long/Long @McpArg parameter; buildArgs -> convertArgumentValue -> toLongExact fails.
Common situations: Clients sending huge IDs or timestamps outside the signed 64-bit range; fractional numbers sent for long fields; JSON numbers parsed as Double then asked to be an exact long.
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 int
- 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/094e16e0cea3f63f.
Report an issue: GitHub.