spring-projects/spring-ai · warning

Tool call arguments are null or empty for MCP tool: <toolNam

Error message

Tool call arguments are null or empty for MCP tool: <toolName>. Using empty JSON object as default.

What it means

SyncMcpToolCallback.call() received a null/empty tool call input and substitutes "{}" instead, logging this warning. The synchronous MCP tool is then invoked with an empty arguments object; tools that require arguments will fail downstream with their own validation error.

Source

Thrown at mcp/common/src/main/java/org/springframework/ai/mcp/SyncMcpToolCallback.java:117

	 * Returns the original MCP tool name without prefixing.
	 * @return the original tool name
	 */
	public String getOriginalToolName() {
		return this.tool.name();
	}

	@Override
	public String call(String toolCallInput) {
		return this.call(toolCallInput, null);
	}

	@Override
	public String call(String toolCallInput, @Nullable ToolContext toolContext) {

		// Handle the possible null parameter situation in streaming mode.
		if (!StringUtils.hasText(toolCallInput)) {
			if (logger.isWarnEnabled()) {
				logger.warn("Tool call arguments are null or empty for MCP tool: " + this.tool.name()
						+ ". Using empty JSON object as default.");
			}
			toolCallInput = "{}";
		}

		Map<String, Object> arguments = jsonHelper.fromJsonToMap(toolCallInput);

		CallToolResult response;
		try {
			var mcpMeta = toolContext != null ? this.toolContextToMcpMetaConverter.convert(toolContext) : null;

			// Use the original tool name, not the prefixed one from getToolDefinition
			var request = CallToolRequest.builder(this.tool.name()).arguments(arguments).meta(mcpMeta).build();

			// Note that we use the original tool name here, not the adapted one from
			// getToolDefinition
			response = this.mcpClient.callTool(request);
		}

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Verify the MCP tool's inputSchema and ensure the model is prompted/schematized to supply required arguments.
  2. Guard the input before calling: substitute a valid JSON object with sensible defaults when input is blank.
  3. If arguments are genuinely optional, treat this warning as informational and move on.
  4. Capture the model's raw tool-call payload in logs to determine why the arguments were missing.

Example fix

// before
String result = syncToolCallback.call(toolCallInput); // may be null in streaming mode
// after
String safeInput = (toolCallInput == null || toolCallInput.isBlank())
        ? "{\"query\":\"\"}" : toolCallInput;
String result = syncToolCallback.call(safeInput);
Defensive patterns

Strategy: type-guard

Validate before calling

if (input == null || input.isBlank()) {
    input = "{\"defaults\":true}"; // provide schema-conformant defaults
}

Type guard

boolean hasToolArguments(String input) {
    return input != null && !input.isBlank();
}

Try / catch

// library substitutes {} silently; guard downstream failures
try {
    String result = syncCallback.call(input == null ? "{}" : input);
} catch (ToolExecutionException e) {
    logger.error("MCP tool failed, likely missing required arguments", e);
}

Prevention

When it happens

Trigger: Calling call() on a sync MCP tool callback where toolCallInput is null/empty/blank — usually when a streaming model emits a tool call with no arguments or the integration forwards an empty string from the model's tool-call payload.

Common situations: Argument-less tool calls in streaming responses; model output truncated so the arguments JSON is missing; wrappers that pass the raw model string straight into the tool callback without checking it.

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


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