{"record":{"id":"144719a253d2d7cd","repo":"spring-projects/spring-ai","slug":"failed-to-convert-jsonvalue-to-string","errorCode":null,"errorMessage":"Failed to convert JsonValue to string","messagePattern":"Failed to convert JsonValue to string","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatModel.java","lineNumber":1174,"sourceCode":"\t}\n\n\t/**\n\t * Converts a {@link JsonValue} to a valid JSON string. Required because\n\t * {@code JsonValue.toString()} produces Java Map format ({@code {key=value}}), not\n\t * valid JSON. Converts to native Java objects first, then serializes with Jackson.\n\t * @param jsonValue the SDK's JsonValue to convert\n\t * @return a valid JSON string\n\t * @throws RuntimeException if serialization fails\n\t */\n\tprivate String convertJsonValueToString(JsonValue jsonValue) {\n\t\ttry {\n\t\t\tvar jsonMapper = tools.jackson.databind.json.JsonMapper.builder().build();\n\t\t\t// Convert to native Java objects first, then serialize with Jackson\n\t\t\tObject nativeValue = convertJsonValueToNative(jsonValue);\n\t\t\treturn jsonMapper.writeValueAsString(nativeValue);\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new RuntimeException(\"Failed to convert JsonValue to string\", e);\n\t\t}\n\t}\n\n\t/**\n\t * Converts a {@link JsonValue} to a native Java object (null, Boolean, Number,\n\t * String, List, or Map) using the SDK's visitor interface.\n\t * @param jsonValue the SDK's JsonValue to convert\n\t * @return the equivalent native Java object, or null for JSON null\n\t */\n\tprivate @Nullable Object convertJsonValueToNative(JsonValue jsonValue) {\n\t\treturn jsonValue.accept(new JsonValue.Visitor<@Nullable Object>() {\n\t\t\t@Override\n\t\t\tpublic @Nullable Object visitNull() {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t@Override\n\t\t\tpublic @Nullable Object visitMissing() {","sourceCodeStart":1156,"sourceCodeEnd":1192,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatModel.java#L1156-L1192","documentation":"AnthropicChatModel serializes a tool-call result JsonValue to a JSON string for the API payload. It first converts the JsonValue to native Java objects and serializes with Jackson; any exception in that pipeline is rethrown as a RuntimeException 'Failed to convert JsonValue to string' with the cause.","triggerScenarios":"A tool execution returns a JsonValue that cannot be converted (unexpected/recursive structure, a JsonValue variant not handled by convertJsonValueToNative) or Jackson fails to serialize the resulting native object.","commonSituations":"Custom tool return values with exotic types; SDK version mismatch changing JsonValue variants; returning objects with circular references or non-Jackson-friendly types from a tool.","solutions":["Inspect the cause for the exact failing node","Return simple types (String, Number, Boolean, Map, List) from @Tool methods","Update spring-ai-anthropic and the Anthropic SDK to matching versions","Pre-stringify or simplify complex tool results before returning them"],"exampleFix":"// before\n@Tool public MyComplexObject lookup(String id) { return new MyComplexObject(...); } // serialization may fail\n// after\n@Tool public Map<String,Object> lookup(String id) { return Map.of(\"name\", obj.getName(), \"value\", obj.getValue()); }","handlingStrategy":"try-catch","validationCode":"// ensure tool returns are Jackson-friendly\nObject result = ...;\njsonMapper.writeValueAsString(result); // dry-run before returning from the tool","typeGuard":"boolean isSimpleValue(Object v) { return v == null || v instanceof String || v instanceof Number || v instanceof Boolean || v instanceof Map || v instanceof List; }","tryCatchPattern":"try { json = serializeToolResult(jsonValue); }\ncatch (RuntimeException e) { json = \"{\\\"error\\\":\\\"tool result serialization failed\\\"}\"; logger.warn(\"Serialization failed\", e); }","preventionTips":["Return Maps/Lists/primitives from @Tool methods","Avoid circular references in tool return objects","Keep the Anthropic SDK and Spring AI versions aligned"],"tags":["anthropic","json-serialization","tools","jackson"],"backgroundTag":"json-serialization-failed","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"}