spring-projects/spring-ai · warning
Tool call arguments are null or empty for tool: ${toolName}.
Error message
Tool call arguments are null or empty for tool: ${toolName}. Using empty JSON object as default. What it means
DefaultToolCallingManager logs this warning when a tool call's arguments string is null or empty, which commonly happens in streaming mode where the LLM may omit the arguments field. Instead of failing, the manager substitutes an empty JSON object "{}" and proceeds with tool execution. The tool then receives no arguments, so any required parameters will be missing.
Source
Thrown at spring-ai-model/src/main/java/org/springframework/ai/model/tool/DefaultToolCallingManager.java:277
.conversationHistory(partialConversationHistory)
.returnDirect(Objects.requireNonNullElse(returnDirect, false))
.build();
throw new ToolCallLimitExceededException(limitBreach.toolName(), limitBreach.limit(),
partialToolExecutionResult);
}
// ToolCallLimitBehavior.RETURN_ERROR_RESPONSE: skip invoking this tool
// call but keep processing the rest of the batch.
continue;
}
String toolInputArguments = toolCall.arguments();
// Handle the possible null parameter situation in streaming mode.
final String finalToolInputArguments;
if (!StringUtils.hasText(toolInputArguments)) {
if (logger.isWarnEnabled()) {
logger.warn("Tool call arguments are null or empty for tool: " + toolName
+ ". Using empty JSON object as default.");
}
finalToolInputArguments = "{}";
}
else {
finalToolInputArguments = toolInputArguments;
}
ToolCallback toolCallback = toolCallbacks.stream()
.filter(tool -> toolName.equals(tool.getToolDefinition().name()))
.findFirst()
.orElseGet(() -> this.resolutionFallbackEnabled ? this.toolCallbackResolver.resolve(toolName) : null);
if (toolCallback == null) {
if (logger.isWarnEnabled()) {
logger.warn(POSSIBLE_LLM_TOOL_NAME_CHANGE_WARNING_START + toolName
+ POSSIBLE_LLM_TOOL_NAME_CHANGE_WARNING_END);
}View on GitHub (pinned to 98a7beda4f)
Solutions
- If the tool has no parameters, ignore the warning — the "{}" default is correct.
- If the tool requires parameters, check that the streaming response is fully aggregated before tool execution (ensure the arguments chunks are merged).
- Verify the model/provider actually supports tool calling with arguments in streaming mode.
- Inspect the raw model response to confirm the LLM is emitting arguments; adjust prompts or upgrade the model if it consistently omits them.
Example fix
// before (tool requiring args, receives {})
@Tool(description="Lookup weather")
String weather(@ToolParam(required = true) String city) { ... }
// after (make the parameter optional / defaulted to survive empty args)
@Tool(description="Lookup weather")
String weather(@ToolParam(required = false) String city) {
if (city == null || city.isBlank()) return "Please provide a city";
...
} Defensive patterns
Strategy: type-guard
Validate before calling
if (toolCall.arguments() == null || toolCall.arguments().isBlank()) {
logger.warn("Tool {} called without arguments; required params will be missing", toolCall.name());
} Type guard
boolean hasArgs(ToolCall c) { return c.arguments() != null && !c.arguments().isBlank(); } Prevention
- Make @Tool parameters optional with defaults so empty {} won't break execution.
- Verify streaming aggregation merges all argument chunks.
- Prefer non-streaming for tools with required parameters.
- Check provider support for arguments in streaming tool calls.
When it happens
Trigger: A streaming LLM response produces a ToolCall with arguments() returning null or blank; the tool call is executed via executeToolCall (invoked from internalToolExecutionResult).
Common situations: Streaming responses from models that omit the arguments field for parameterless tools; partial/empty argument chunks in streaming aggregation; models that emit a tool call without an arguments JSON block.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Currently only one tool call is supported per message!
- Currently only one tool call is supported per message!
- Tool call arguments are null or empty for MCP tool: <toolNam
- Tool call arguments are null or empty for MCP tool: <toolNam
- Conversion from JSON failed
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/170e2378302ea7f3.
Report an issue: GitHub.