spring-projects/spring-ai · error · java.lang.RuntimeException

Failed to convert map to JSON

Error message

Failed to convert map to JSON

What it means

mapToJson() serializes a Map<String,Object> to a JSON string using the model's ObjectMapper for Gemini function-call arguments. Serialization failure is unexpected for in-memory maps but possible with unserializable values (e.g. objects with no accessible properties, cyclic references, or incompatible Jackson modules), and is rethrown as a RuntimeException with this message. It is raised while building function call arguments (functionArguments).

Source

Thrown at models/spring-ai-google-genai/src/main/java/org/springframework/ai/google/genai/GoogleGenAiChatModel.java:385

			}
			else {
				// It's a primitive or other type, wrap it
				Map<String, Object> wrapper = new HashMap<>();
				wrapper.put("result", parsed);
				return wrapper;
			}
		}
		catch (Exception e) {
			throw new RuntimeException("Failed to parse JSON: " + json, e);
		}
	}

	private String mapToJson(Map<String, Object> map) {
		try {
			return this.jsonMapper.writeValueAsString(map);
		}
		catch (Exception e) {
			throw new RuntimeException("Failed to convert map to JSON", e);
		}
	}

	private Schema jsonToSchema(String json) {
		try {
			return this.jsonMapper.readValue(json, Schema.class);
		}
		catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	// https://googleapis.github.io/java-genai/javadoc/com/google/genai/types/GenerationConfig.html
	@Override
	public ChatResponse call(Prompt prompt) {
		var requestPrompt = this.buildRequestPrompt(prompt);
		return this.internalCall(requestPrompt, null);
	}

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Return simple, JSON-friendly types (Map<String,String/Number>, records, POJOs with getters) from tool functions.
  2. Register the needed Jackson modules (e.g. JavaTimeModule) on the jsonMapper used by the chat model, or configure the model's JsonMapper.
  3. Break cyclic references (use @JsonIgnore or DTOs) before returning data used as function-call arguments.

Example fix

// before
Map<String, Object> result = Map.of("created", LocalDateTime.now()); // fails without JavaTimeModule

// after
Map<String, Object> result = Map.of("created", LocalDateTime.now().toString());
Defensive patterns

Strategy: try-catch

Try / catch

try {
    String json = mapToJson(map);
}
catch (RuntimeException e) {
    logger.warn("Map not serializable: {}", e.getMessage());
    // sanitize map values or fall back to a safe DTO
}

Prevention

When it happens

Trigger: A tool function returns or builds arguments whose map contains values Jackson cannot serialize (cyclic object graphs, types without getters, custom classes lacking a serializer) when functionArguments assembles the FunctionCall payload.

Common situations: Returning domain objects with circular references from @Tool methods; maps containing exotic types (InputStream, LocalDateTime without JavaTimeModule registered); custom JsonMapper configurations missing required modules.

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/afbf6802b6e7faa2. Report an issue: GitHub.