Skip to content

Wrap missing primitive tool parameter errors as ToolExecutionException - #6743

Open
arimu1 wants to merge 1 commit into
spring-projects:mainfrom
arimu1:GH-6723-method-tool-callback-primitive
Open

Wrap missing primitive tool parameter errors as ToolExecutionException#6743
arimu1 wants to merge 1 commit into
spring-projects:mainfrom
arimu1:GH-6723-method-tool-callback-primitive

Conversation

@arimu1

@arimu1 arimu1 commented Aug 5, 2026

Copy link
Copy Markdown

Thank you for taking time to contribute this pull request!
You might have already read the contributor guide, but as a reminder, please make sure to:

  • Add a Signed-off-by line to each commit (git commit -s) per the DCO
  • Rebase your changes on the latest main branch and squash your commits
  • Add/Update unit tests as needed
  • Run a build and make sure all tests pass prior to submission

For more details, please check the contributor guide.
Thank you upfront!


Fixes #6723

Problem

When the model omits an argument for a @Tool method parameter that is a primitive (boolean, int, …), MethodToolCallback resolves it to null and Method.invoke throws a raw IllegalArgumentException. That exception is not an InvocationTargetException, so callMethod did not wrap it as ToolExecutionException. The failure escaped tool-calling machinery and aborted the entire chat turn instead of being handled by ToolExecutionExceptionProcessor.

Solution

  1. Early validation in buildMethodArguments: if a looked-up argument is null and the parameter type is primitive, throw ToolExecutionException with an IllegalArgumentException that names the parameter and type (actionable for the model).
  2. Safety net in callMethod: catch IllegalArgumentException from Method.invoke and wrap it as ToolExecutionException, mirroring the existing InvocationTargetException handling.

Wrapper types (Boolean, Integer, …) are unchanged: missing values still arrive as null.

Tests

  • New MethodToolCallbackPrimitiveArgumentTests (4 tests):
    • missing primitive boolean / intToolExecutionException with parameter name
    • missing boxed Boolean still succeeds with null
    • present primitive succeeds
  • Also re-ran MethodToolCallbackExceptionHandlingTest and MethodToolCallbackGenericTypesTest
./mvnw -pl spring-ai-model -am test \
  -Dtest=MethodToolCallbackPrimitiveArgumentTests,MethodToolCallbackExceptionHandlingTest,MethodToolCallbackGenericTypesTest \
  -Dsurefire.failIfNoSpecifiedTests=false

Result: 9 tests, 0 failures (Temurin 21). DCO: Signed-off-by present.

Notes

This keeps the fix scoped to the reported MethodToolCallback failure path. Broader “required parameter” enforcement across schema generation and MCP annotations (as discussed on the issue) is left for a follow-up if maintainers want that direction.

When a model omits an argument for a @tool method parameter that is a
primitive, Method.invoke threw a raw IllegalArgumentException that
escaped callMethod unwrapped. Catch that path and fail earlier in
buildMethodArguments with the parameter name so ToolExecutionExceptionProcessor
can return the error to the model instead of aborting the chat turn.

Fixes spring-projects#6723

Signed-off-by: arimu1 <19286898+arimu1@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MethodToolCallback: a missing primitive tool parameter throws a raw IllegalArgumentException that bypasses ToolExecutionException

2 participants