{"record":{"id":"b5534fe1fd163d4c","repo":"spring-projects/spring-ai","slug":"failed-to-parse-json","errorCode":null,"errorMessage":"Failed to parse JSON: ","messagePattern":"Failed to parse JSON: ","errorType":"exception","errorClass":"java.lang.RuntimeException","httpStatus":null,"severity":"error","filePath":"models/spring-ai-google-genai/src/main/java/org/springframework/ai/google/genai/GoogleGenAiChatModel.java","lineNumber":376,"sourceCode":"\t\t\tif (parsed instanceof List) {\n\t\t\t\t// It's an array, wrap it in a map with \"result\" key\n\t\t\t\tMap<String, Object> wrapper = new HashMap<>();\n\t\t\t\twrapper.put(\"result\", parsed);\n\t\t\t\treturn wrapper;\n\t\t\t}\n\t\t\telse if (parsed instanceof Map) {\n\t\t\t\t// It's already a map, return it\n\t\t\t\treturn (Map<String, Object>) parsed;\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// It's a primitive or other type, wrap it\n\t\t\t\tMap<String, Object> wrapper = new HashMap<>();\n\t\t\t\twrapper.put(\"result\", parsed);\n\t\t\t\treturn wrapper;\n\t\t\t}\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new RuntimeException(\"Failed to parse JSON: \" + json, e);\n\t\t}\n\t}\n\n\tprivate String mapToJson(Map<String, Object> map) {\n\t\ttry {\n\t\t\treturn this.jsonMapper.writeValueAsString(map);\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new RuntimeException(\"Failed to convert map to JSON\", e);\n\t\t}\n\t}\n\n\tprivate Schema jsonToSchema(String json) {\n\t\ttry {\n\t\t\treturn this.jsonMapper.readValue(json, Schema.class);\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new RuntimeException(e);","sourceCodeStart":358,"sourceCodeEnd":394,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/models/spring-ai-google-genai/src/main/java/org/springframework/ai/google/genai/GoogleGenAiChatModel.java#L358-L394","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nMap<String, Object> args = model.parseJsonToMap(raw); // throws on malformed model output\n\n// after\nMap<String, Object> args;\ntry {\n    args = model.parseJsonToMap(raw);\n}\ncatch (RuntimeException e) {\n    logger.warn(\"Malformed tool JSON: {}\", e.getMessage());\n    args = Map.of();\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    Map<String, Object> args = parseJsonToMap(json);\n}\ncatch (RuntimeException e) {\n    logger.warn(\"Malformed JSON payload: {}\", e.getMessage());\n    // return structured error result to the model or fall back\n}","preventionTips":["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."],"tags":["chat","json","function-calling","parsing"],"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-14T05:17:10.506Z"}