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

  1. Use double, BigDecimal, or String parameter types for values that may exceed long range or be fractional.
  2. Have the client send an integer literal within [-2^63, 2^63-1].
  3. 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

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


AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11). Data as JSON: /api/errors/094e16e0cea3f63f. Report an issue: GitHub.