spring-projects/spring-ai · error · java.lang.RuntimeException
Failed to parse JSON:
Error message
Failed to parse JSON:
What it means
parseJsonToMap() parses model/function-call JSON payloads into a Map, wrapping non-object results under a "result" key. If the JSON cannot be parsed at all, the exception (including the offending json string) is rethrown as a RuntimeException with this message. It is raised when converting tool-call argument or response payloads during Gemini function calling.
Source
Thrown at models/spring-ai-google-genai/src/main/java/org/springframework/ai/google/genai/GoogleGenAiChatModel.java:376
if (parsed instanceof List) {
// It's an array, wrap it in a map with "result" key
Map<String, Object> wrapper = new HashMap<>();
wrapper.put("result", parsed);
return wrapper;
}
else if (parsed instanceof Map) {
// It's already a map, return it
return (Map<String, Object>) parsed;
}
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);View on GitHub (pinned to 98a7beda4f)
Solutions
- Log the offending 'json' payload from the RuntimeException message and sanitize/repair the source producing it (often the model output).
- Tighten function tool descriptions and use Gemini's response schema so the model produces well-formed JSON arguments.
- Wrap tool invocation points with a defensive parse: catch the RuntimeException and return a structured error result back to the model instead of crashing.
Example fix
// before
Map<String, Object> args = model.parseJsonToMap(raw); // throws on malformed model output
// after
Map<String, Object> args;
try {
args = model.parseJsonToMap(raw);
}
catch (RuntimeException e) {
logger.warn("Malformed tool JSON: {}", e.getMessage());
args = Map.of();
} Defensive patterns
Strategy: try-catch
Try / catch
try {
Map<String, Object> args = parseJsonToMap(json);
}
catch (RuntimeException e) {
logger.warn("Malformed JSON payload: {}", e.getMessage());
// return structured error result to the model or fall back
} Prevention
- Provide clear response schemas and tool descriptions so the model emits valid JSON.
- Log the offending payload from the exception message for diagnosis.
- Handle truncated model output (token limits) which commonly breaks JSON.
When it happens
Trigger: A Gemini function call whose argument/response string is not valid JSON (truncated output, model-generated malformed JSON, or raw text where JSON was expected) is passed through messageToGeminiParts/partBuilder's parseJsonToMap path.
Common situations: Model emitting malformed or truncated JSON in function-call arguments (hit output-token limits); custom tools returning non-JSON strings that get re-parsed; embedded control characters or single-quoted pseudo-JSON from the model.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to convert map to JSON
- Error parsing JSON-RPC message:
- Failed to parse JSON:
- Conversion from JSON to %s failed
- Failed to parse JSON Schema
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/b5534fe1fd163d4c.
Report an issue: GitHub.