{"record":{"id":"45bc98c81c17ea9c","repo":"spring-projects/spring-ai","slug":"failed-to-parse-tool-arguments-json-argumentsjs","errorCode":null,"errorMessage":"Failed to parse tool arguments JSON: + argumentsJson","messagePattern":"Failed to parse tool arguments JSON: \\+ argumentsJson","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatModel.java","lineNumber":1250,"sourceCode":"\t * string and creates the proper SDK input format.\n\t * @param argumentsJson the JSON string containing tool call arguments\n\t * @return a ToolUseBlockParam.Input with the parsed arguments\n\t */\n\tprivate ToolUseBlockParam.Input buildToolInput(String argumentsJson) {\n\t\tToolUseBlockParam.Input.Builder inputBuilder = ToolUseBlockParam.Input.builder();\n\t\tif (argumentsJson != null && !argumentsJson.isEmpty()) {\n\t\t\ttry {\n\t\t\t\tvar jsonMapper = tools.jackson.databind.json.JsonMapper.builder().build();\n\t\t\t\tjava.util.Map<String, Object> arguments = jsonMapper.readValue(argumentsJson,\n\t\t\t\t\t\tnew tools.jackson.core.type.TypeReference<java.util.Map<String, Object>>() {\n\t\t\t\t\t\t});\n\t\t\t\tfor (java.util.Map.Entry<String, Object> entry : arguments.entrySet()) {\n\t\t\t\t\tinputBuilder.putAdditionalProperty(entry.getKey(), JsonValue.from(entry.getValue()));\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (Exception e) {\n\t\t\t\tif (logger.isWarnEnabled()) {\n\t\t\t\t\tlogger.warn(\"Failed to parse tool arguments JSON: \" + argumentsJson, e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn inputBuilder.build();\n\t}\n\n\t/**\n\t * Converts a Spring AI {@link ToolDefinition} to an Anthropic SDK {@link Tool}.\n\t * <p>\n\t * Spring AI provides the input schema as a JSON string, but the SDK expects a\n\t * structured {@code Tool.InputSchema} built via the builder pattern.\n\t * <p>\n\t * Conversion: parses the JSON schema to a Map, extracts \"properties\" (added via\n\t * {@code putAdditionalProperty()}), extracts \"required\" fields (added via\n\t * {@code addRequired()}), then builds the Tool with name, description, and schema.\n\t * @param toolDefinition the tool definition with name, description, and JSON schema\n\t * @return the Anthropic SDK Tool\n\t * @throws RuntimeException if the JSON schema cannot be parsed","sourceCodeStart":1232,"sourceCodeEnd":1268,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatModel.java#L1232-L1268","documentation":"A warning logged when building an Anthropic tool_use input from a tool call whose arguments JSON cannot be parsed or converted to JsonValue. The method returns the (possibly empty/partial) inputBuilder anyway, so the tool call may be sent with missing arguments. It indicates malformed argumentsJson coming from the model or from a previous round-trip.","triggerScenarios":"Converting a Spring AI ToolCall whose arguments() string is not valid JSON, or whose parsed values cannot be converted by JsonValue.from (e.g. exotic nested types) while reconstructing a follow-up Anthropic request with tool results.","commonSituations":"Model emitted truncated or non-JSON tool arguments; custom ToolCallingChatOptions implementations producing hand-built argument strings; echoing back tool calls whose arguments were serialized by a different schema; double-encoded JSON strings.","solutions":["Validate/repair the tool arguments JSON before returning the ToolCall from your tool callback chain","Log and inspect the raw argumentsJson string that fails to parse","Ensure your function-calling response handling stores arguments as canonical JSON","Upgrade spring-ai-anthropic for more tolerant argument parsing","If you control the model prompt, constrain the tool schema so arguments are always valid JSON"],"exampleFix":"// before\nString argumentsJson = toolCall.arguments(); // may be malformed\n// after\nString argumentsJson = toolCall.arguments();\ntry {\n    JsonValue.from(argumentsJson); // validate early\n}\ncatch (Exception e) {\n    argumentsJson = \"{}\"; // or repair/default before sending\n}","handlingStrategy":"validation","validationCode":"boolean isValidToolArgsJson(String args) {\n    if (args == null || args.isBlank()) return false;\n    try { JsonValue.from(args); return true; }\n    catch (Exception e) { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n    chatModel.call(new Prompt(prompt, toolOptions));\n}\ncatch (Exception e) {\n    logger.warn(\"Tool-call round trip failed, possibly malformed arguments\", e);\n    // retry with repaired/default arguments or without the tool result\n}","preventionTips":["Validate toolCall.arguments() parses as JSON before feeding it back into follow-up requests","Define strict JSON schemas for your tool @Tool methods so model output stays parseable","Never hand-build tool argument strings; serialize with a JSON mapper","Log the offending argumentsJson string when the warning fires to spot truncation early"],"tags":["anthropic","json","tool-calls","parse-error","spring-ai"],"backgroundTag":"json-parse-error","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}