{"record":{"id":"d1a9159c1d0ad8c9","repo":"alibaba/spring-ai-alibaba","slug":"chatclient-successfully-returned-but-the-returned","errorCode":null,"errorMessage":"ChatClient successfully returned, but the returned json is invalid.","messagePattern":"ChatClient successfully returned, but the returned json is invalid\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"spring-boot-starters/spring-ai-alibaba-starter-builtin-nodes/src/main/java/com/alibaba/cloud/ai/graph/node/ParameterParsingNode.java","lineNumber":203,"sourceCode":"\t\t\t\t.chatResponse();\n\n\t\t\tString rawJson = Optional.ofNullable(response)\n\t\t\t\t.orElseThrow(() -> new RuntimeException(\"chat response is null\"))\n\t\t\t\t.getResult()\n\t\t\t\t.getOutput()\n\t\t\t\t.getText();\n\t\t\t// Remove Markdown markers\n\t\t\tif (rawJson != null) {\n\t\t\t\trawJson = rawJson.replace(\"```json\", \"\").replace(\"```\", \"\").trim();\n\t\t\t}\n\n\t\t\tMap<String, Object> result = new HashMap<>();\n\t\t\tResponse responseJson;\n\t\t\ttry {\n\t\t\t\tresponseJson = OBJECT_MAPPER.readValue(rawJson, Response.class);\n\t\t\t}\n\t\t\tcatch (JsonProcessingException e) {\n\t\t\t\tthrow new RuntimeException(\"ChatClient successfully returned, but the returned json is invalid.\");\n\t\t\t}\n\n\t\t\tif (responseJson.isSuccess()) {\n\t\t\t\tif (responseJson.data() == null) {\n\t\t\t\t\tthrow new RuntimeException(\"ChatClient successfully returned, but the returned data is invalid.\");\n\t\t\t\t}\n\t\t\t\tresult.put(successKey, true);\n\t\t\t\tresult.put(dataKey, responseJson.data());\n\t\t\t\tresult.put(reasonKey, \"success\");\n\t\t\t}\n\t\t\telse {\n\t\t\t\tresult.put(successKey, false);\n\t\t\t\tresult.put(reasonKey, Optional.ofNullable(responseJson.reason()).orElse(\"reason is empty\"));\n\t\t\t}\n\n\t\t\treturn result;\n\t\t}\n\t\tcatch (Exception e) {","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-boot-starters/spring-ai-alibaba-starter-builtin-nodes/src/main/java/com/alibaba/cloud/ai/graph/node/ParameterParsingNode.java#L185-L221","documentation":"ParameterParsingNode.apply() asks the ChatClient to return JSON, then deserializes it into the Response record with Jackson. If ChatClient succeeded but its raw output is not valid JSON for the Response schema, JsonProcessingException is caught and rethrown as RuntimeException('ChatClient successfully returned, but the returned json is invalid.').","triggerScenarios":"The LLM reply (rawJson) is malformed JSON, wrapped in markdown code fences, or does not match the Response record fields, making OBJECT_MAPPER.readValue fail.","commonSituations":"Model ignoring the JSON-format instruction and adding prose or ```json fences; temperature too high causing hallucinated structure; prompt template not requesting strict JSON output.","solutions":["Inspect/parse rawJson: strip markdown code fences before expecting valid JSON","Strengthen the prompt/instruction to demand strict, fence-free JSON and set a low temperature","Use ChatClient's structured-output/entity mapping (response entity) instead of manual string parsing","Catch this RuntimeException downstream and retry the LLM call"],"exampleFix":"// before\nresponseJson = OBJECT_MAPPER.readValue(rawJson, Response.class);\n// after\nString cleaned = rawJson.replaceAll(\"^```(json)?|```$\", \"\").trim();\nresponseJson = OBJECT_MAPPER.readValue(cleaned, Response.class);","handlingStrategy":"try-catch","validationCode":"String cleaned = rawJson == null ? \"\" : rawJson.replaceAll(\"^\\\\s*```(json)?|```\\\\s*$\", \"\").trim();\nboolean looksLikeJson = cleaned.startsWith(\"{\") && cleaned.endsWith(\"}\");","typeGuard":"static boolean isParseableResponse(String raw) { try { MAPPER.readValue(raw, Response.class); return true; } catch (Exception e) { return false; } }","tryCatchPattern":"try { out = node.apply(state); } catch (RuntimeException e) { if (e.getMessage().contains(\"returned json is invalid\")) { retryLlmCall(); } }","preventionTips":["Instruct the model to output strict JSON without markdown fences","Use low temperature and few-shot JSON examples in the prompt","Prefer ChatClient structured output (.entity(Response.class)) over manual parsing"],"tags":["llm-output","json","parsing"],"backgroundTag":"invalid-json-response","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}