{"record":{"id":"5da7985914fc6b63","repo":"alibaba/spring-ai-alibaba","slug":"chatclient-call-return-null","errorCode":null,"errorMessage":"ChatClient Call Return Null...","messagePattern":"ChatClient Call Return Null\\.\\.\\.","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/AgentNode.java","lineNumber":134,"sourceCode":"\t}\n\n\t@Override\n\tpublic Map<String, Object> apply(OverAllState state) throws Exception {\n\t\tString userPrompt = new PromptTemplate(this.userPrompt).render(state.data());\n\t\tString systemPrompt = new PromptTemplate(this.systemPrompt).render(state.data());\n\t\tString output = switch (this.strategy) {\n\t\t\tcase TOOL_CALLING, REACT -> {\n\t\t\t\t// Retry mechanism\n\t\t\t\ttry {\n\t\t\t\t\tyield this.retryTemplate.execute(retryContext -> {\n\t\t\t\t\t\tString content = this.chatClient.prompt(systemPrompt)\n\t\t\t\t\t\t\t.toolCallbacks(this.toolCallbacks)\n\t\t\t\t\t\t\t.user(userPrompt)\n\t\t\t\t\t\t\t.call()\n\t\t\t\t\t\t\t.content();\n\t\t\t\t\t\tif (content == null) {\n\t\t\t\t\t\t\tlogger.warn(\"ChatClient Call Return Null...\");\n\t\t\t\t\t\t\tthrow new RuntimeException(\"ChatClient Call Return Null...\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn content;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tcatch (Exception e) {\n\t\t\t\t\tlogger.error(\"Attempted to the maximum number of times but still failed!\");\n\t\t\t\t\tyield null;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\treturn Map.of(this.outputKey, output == null ? \"\" : output);\n\t}\n\n\tpublic static Builder builder() {\n\t\treturn new Builder();\n\t}\n\n\tpublic static class Builder {","sourceCodeStart":116,"sourceCodeEnd":152,"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/AgentNode.java#L116-L152","documentation":"AgentNode.apply throws this RuntimeException when ChatClient.call().content() returns null after the retry-wrapped invocation, i.e. the model produced no textual content. The node logs a warning then fails fast because downstream nodes expect a non-null string output under outputKey.","triggerScenarios":"The chat model returns an empty/no-content response (e.g. the response contains only tool calls that were not executed, a stop with no text, or an empty completion) while running the agent's RetryTemplate callback.","commonSituations":"Model configured with tools but no final text answer generated; max_tokens set so low the response is empty; provider returns empty content on safety-filtered prompts; using a model/adapter whose content mapping yields null.","solutions":["Check the model response in logs to see why content is null (tool calls, filtering, token limit)","Raise max_tokens or adjust prompts so the model produces final text","Verify tool execution/conversion so the loop ends with a textual answer","Wrap apply/call sites in try-catch and provide a fallback output value"],"exampleFix":"// before\nString content = chatClient.prompt().user(userPrompt).call().content();\n// after\nString content = chatClient.prompt().user(userPrompt).call().content();\nif (content == null || content.isBlank()) { content = \"(no content generated)\"; }","handlingStrategy":"try-catch","validationCode":"// verify model reachable and producing content in a preflight call\nString probe = chatClient.prompt().user(\"ping\").call().content();\nif (probe == null || probe.isBlank()) throw new IllegalStateException(\"model returns empty content\");","typeGuard":null,"tryCatchPattern":"try {\n    output = agentNode.apply(state);\n} catch (RuntimeException e) {\n    if (e.getMessage().contains(\"Return Null\")) {\n        state.put(outputKey, fallbackAnswer);\n    } else throw e;\n}","preventionTips":["Set adequate max_tokens and avoid prompts that end in pure tool-call loops","Inspect raw ChatResponse (not just content()) when debugging empty answers","Configure the retryTemplate with backoff for transient provider hiccups"],"tags":["chatclient","null-content","llm-response","runtime-exception"],"backgroundTag":"empty-api-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"}