spring-projects/spring-ai · error · RuntimeException

Failed to convert JsonValue to string

Error message

Failed to convert JsonValue to string

What it means

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.

Source

Thrown at models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatModel.java:1174

	}

	/**
	 * Converts a {@link JsonValue} to a valid JSON string. Required because
	 * {@code JsonValue.toString()} produces Java Map format ({@code {key=value}}), not
	 * valid JSON. Converts to native Java objects first, then serializes with Jackson.
	 * @param jsonValue the SDK's JsonValue to convert
	 * @return a valid JSON string
	 * @throws RuntimeException if serialization fails
	 */
	private String convertJsonValueToString(JsonValue jsonValue) {
		try {
			var jsonMapper = tools.jackson.databind.json.JsonMapper.builder().build();
			// Convert to native Java objects first, then serialize with Jackson
			Object nativeValue = convertJsonValueToNative(jsonValue);
			return jsonMapper.writeValueAsString(nativeValue);
		}
		catch (Exception e) {
			throw new RuntimeException("Failed to convert JsonValue to string", e);
		}
	}

	/**
	 * Converts a {@link JsonValue} to a native Java object (null, Boolean, Number,
	 * String, List, or Map) using the SDK's visitor interface.
	 * @param jsonValue the SDK's JsonValue to convert
	 * @return the equivalent native Java object, or null for JSON null
	 */
	private @Nullable Object convertJsonValueToNative(JsonValue jsonValue) {
		return jsonValue.accept(new JsonValue.Visitor<@Nullable Object>() {
			@Override
			public @Nullable Object visitNull() {
				return null;
			}

			@Override
			public @Nullable Object visitMissing() {

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Inspect the cause for the exact failing node
  2. Return simple types (String, Number, Boolean, Map, List) from @Tool methods
  3. Update spring-ai-anthropic and the Anthropic SDK to matching versions
  4. Pre-stringify or simplify complex tool results before returning them

Example fix

// before
@Tool public MyComplexObject lookup(String id) { return new MyComplexObject(...); } // serialization may fail
// after
@Tool public Map<String,Object> lookup(String id) { return Map.of("name", obj.getName(), "value", obj.getValue()); }
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure tool returns are Jackson-friendly
Object result = ...;
jsonMapper.writeValueAsString(result); // dry-run before returning from the tool

Type guard

boolean isSimpleValue(Object v) { return v == null || v instanceof String || v instanceof Number || v instanceof Boolean || v instanceof Map || v instanceof List; }

Try / catch

try { json = serializeToolResult(jsonValue); }
catch (RuntimeException e) { json = "{\"error\":\"tool result serialization failed\"}"; logger.warn("Serialization failed", e); }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.

Related errors


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