{"record":{"id":"0ae120325b886202","repo":"spring-projects/spring-ai","slug":"no-chat-completion-returned-for-prompt-prompt","errorCode":null,"errorMessage":"No chat completion returned for prompt: + prompt","messagePattern":"No chat completion returned for prompt: \\+ prompt","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"models/spring-ai-deepseek/src/main/java/org/springframework/ai/deepseek/DeepSeekChatModel.java","lineNumber":157,"sourceCode":"\n\t\tChatModelObservationContext observationContext = ChatModelObservationContext.builder()\n\t\t\t.prompt(prompt)\n\t\t\t.provider(DeepSeekConstants.PROVIDER_NAME)\n\t\t\t.build();\n\n\t\tChatResponse response = ChatModelObservationDocumentation.CHAT_MODEL_OPERATION\n\t\t\t.observation(this.observationConvention, DEFAULT_OBSERVATION_CONVENTION, () -> observationContext,\n\t\t\t\t\tthis.observationRegistry)\n\t\t\t.observe(() -> {\n\n\t\t\t\tResponseEntity<ChatCompletion> completionEntity = RetryUtils.execute(this.retryTemplate,\n\t\t\t\t\t\t() -> this.deepSeekApi.chatCompletionEntity(request));\n\n\t\t\t\tvar chatCompletion = completionEntity.getBody();\n\n\t\t\t\tif (chatCompletion == null) {\n\t\t\t\t\tif (logger.isWarnEnabled()) {\n\t\t\t\t\t\tlogger.warn(\"No chat completion returned for prompt: \" + prompt);\n\t\t\t\t\t}\n\t\t\t\t\treturn new ChatResponse(List.of());\n\t\t\t\t}\n\n\t\t\t\tList<Choice> choices = chatCompletion.choices();\n\t\t\t\tif (choices == null) {\n\t\t\t\t\tif (logger.isWarnEnabled()) {\n\t\t\t\t\t\tlogger.warn(\"No choices returned for prompt: \" + prompt);\n\t\t\t\t\t}\n\t\t\t\t\treturn new ChatResponse(List.of());\n\t\t\t\t}\n\n\t\t\t\tList<Generation> generations = choices.stream().map(choice -> {\n\t\t\t// @formatter:off\n\t\t\t\t\tMap<String, Object> metadata = Map.of(\n\t\t\t\t\t\t\t\"id\", chatCompletion.id() != null ? chatCompletion.id() : \"\",\n\t\t\t\t\t\t\t\"role\", choice.message().role() != null ? choice.message().role().name() : \"\",\n\t\t\t\t\t\t\t\"index\", choice.index(),","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/models/spring-ai-deepseek/src/main/java/org/springframework/ai/deepseek/DeepSeekChatModel.java#L139-L175","documentation":"Warning logged by DeepSeekChatModel.internalCall() when the HTTP response body from deepSeekApi.chatCompletionEntity() is null — i.e. DeepSeek returned no ChatCompletion object at all. The method returns an empty ChatResponse (empty generations list) instead of throwing, so callers see a response with no content rather than an error.","triggerScenarios":"deepseekApi.chatCompletionEntity(request) executes successfully via RetryUtils but ResponseEntity.getBody() is null — server returned an empty body, or a non-deserializable/empty payload after retries.","commonSituations":"DeepSeek API outages or partial incidents returning 200 with empty body; proxy/gateway stripping the body; invalid DeepSeek API key hitting an endpoint that returns an unexpected empty response; transient network issues that exhausted retries with empty results.","solutions":["Check the DeepSeek API status and your API key validity; an auth or server problem often surfaces as a null body.","Enable wire-level logging (e.g. RestClient/RestTemplate interceptor) to inspect the raw HTTP response.","Guard the caller against ChatResponse with empty generations before using getResult().","Configure the RetryTemplate with a backoff for transient empty responses."],"exampleFix":"// before\nChatResponse response = chatModel.call(new Prompt(prompt));\nString text = response.getResult().getOutput().getText(); // NPE if empty\n// after\nString text = (response.getResults() == null || response.getResults().isEmpty())\n        ? \"\" : response.getResult().getOutput().getText();","handlingStrategy":"try-catch","validationCode":"Assert.hasText(apiKey, \"DeepSeek API key must be set\"); // and verify endpoint reachability before batch jobs","typeGuard":"static boolean isEmpty(ChatResponse r) { return r == null || r.getResults() == null || r.getResults().isEmpty(); }","tryCatchPattern":"ChatResponse r = chatModel.call(new Prompt(prompt));\nif (isEmpty(r)) { metrics.increment(\"deepseek.empty.response\"); return fallbackAnswer; }","preventionTips":["Validate the DeepSeek API key before production traffic","Add an interceptor logging non-2xx and empty bodies","Monitor DeepSeek status page and alert on spikes of empty completions"],"tags":["deepseek","chat-completion","null-response","http"],"backgroundTag":"empty-response-body","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"}