Skip to content

NumberFormatException when model returns scientific notation (e.g., “1.5009969E7”) for int parameter in tool method #2995

@Oren-Peer

Description

@Oren-Peer

Bug description
When using the @tool annotation to define a method with an int parameter, and the model returns a numeric value in scientific notation (e.g., "1.5009969E7"), Spring AI’s internal JsonParser attempts to parse it using Integer.parseInt, which fails with a NumberFormatException.

java.lang.NumberFormatException: For input string: \"1.5009969E7\"
	 java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67) ~[?:?]
	 java.base/java.lang.Integer.parseInt(Integer.java:588) ~[?:?]
	 java.base/java.lang.Integer.parseInt(Integer.java:685) ~[?:?]
	 org.springframework.ai.util.json.JsonParser.toTypedObject(JsonParser.java:131) ~[spring-ai-model-1.0.0-M8.jar:1.0.0-M8]
	 org.springframework.ai.tool.method.MethodToolCallback.buildTypedArgument(MethodToolCallback.java:148) ~[spring-ai-model-1.0.0-M8.jar:1.0.0-M8]
	 org.springframework.ai.tool.method.MethodToolCallback.lambda$buildMethodArguments$1(MethodToolCallback.java:139) ~[spring-ai-model-1.0.0-M8.jar:1.0.0-M8]
	 java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:215) ~[?:?]
	 java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:1024) ~[?:?]
	 java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:570) ~[?:?]
	 java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:560) ~[?:?]
	 java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:636) ~[?:?]
	 java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:291) ~[?:?]
	 java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:656) ~[?:?]
	 java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:662) ~[?:?]
	 org.springframework.ai.tool.method.MethodToolCallback.buildMethodArguments(MethodToolCallback.java:140) ~[spring-ai-model-1.0.0-M8.jar:1.0.0-M8]
	 org.springframework.ai.tool.method.MethodToolCallback.call(MethodToolCallback.java:107) ~[spring-ai-model-1.0.0-M8.jar:1.0.0-M8]
	 org.springframework.ai.model.tool.DefaultToolCallingManager.executeToolCall(DefaultToolCallingManager.java:205) ~[spring-ai-model-1.0.0-M8.jar:1.0.0-M8]
	 org.springframework.ai.model.tool.DefaultToolCallingManager.executeToolCalls(DefaultToolCallingManager.java:128) ~[spring-ai-model-1.0.0-M8.jar:1.0.0-M8]
	 org.springframework.ai.vertexai.gemini.schema.VertexToolCallingManager.executeToolCalls(VertexToolCallingManager.java:94) ~[spring-ai-vertex-ai-gemini-1.0.0-M8.jar:1.0.0-M8]
	 org.springframework.ai.vertexai.gemini.VertexAiGeminiChatModel.lambda$internalStream$8(VertexAiGeminiChatModel.java:514) ~[spring-ai-vertex-ai-gemini-1.0.0-M8.jar:1.0.0-M8]
	 reactor.core.publisher.FluxDefer.subscribe(FluxDefer.java:46) ~[reactor-core-3.7.2.jar:3.7.2]
	 reactor.core.publisher.FluxSubscribeOn$SubscribeOnSubscriber.run(FluxSubscribeOn.java:194) ~[reactor-core-3.7.2.jar:3.7.2]
	 reactor.core.scheduler.WorkerTask.call(WorkerTask.java:84) ~[reactor-core-3.7.2.jar:3.7.2]
	 reactor.core.scheduler.WorkerTask.call(WorkerTask.java:37) ~[reactor-core-3.7.2.jar:3.7.2]
	 java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) ~[?:?]
	 java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) ~[?:?]
	 java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[?:?]
	 java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[?:?]
	 java.base/java.lang.Thread.run(Thread.java:1575) [?:?]

Environment
• Spring AI version: 1.0.0-M8
• Java version: 22
• Model: Vertex AI Gemini
• Tool method used with @tool

Steps to reproduce

  1. Create a tool method with a numeric parameter:
@Tool(description = "Get the Object by its id")
public Object getById(int id) {
    ...
}
  1. Have the model generate a response calling the tool with a large value like "1.5009969E7" (i.e., scientific notation).
  2. The framework tries to convert this value to int using Integer.parseInt(...), which fails.
    org.springframework.ai.util.json.JsonParser

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions