{"record":{"id":"05a80a44a3501bc4","repo":"spring-projects/spring-ai","slug":"no-choices-returned-for-prompt-prompt","errorCode":null,"errorMessage":"No choices returned for prompt: + prompt","messagePattern":"No choices 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":165,"sourceCode":"\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(),\n\t\t\t\t\t\t\t\"finishReason\", choice.finishReason() != null ? choice.finishReason().name() : \"\");\n\t\t\t\t\t// @formatter:on\n\t\t\t\t\treturn buildGeneration(choice, metadata);\n\t\t\t\t}).toList();\n\n\t\t\t\t// Current usage\n\t\t\t\tChatCompletion body = completionEntity.getBody();\n\t\t\t\tAssert.state(body != null, \"Body must not be null\");","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/models/spring-ai-deepseek/src/main/java/org/springframework/ai/deepseek/DeepSeekChatModel.java#L147-L183","documentation":"Warning logged by DeepSeekChatModel.internalCall() when the ChatCompletion body exists but its choices list is null. Like the null-body case, it returns an empty ChatResponse, so the caller gets a structurally valid response with zero generations instead of an exception.","triggerScenarios":"DeepSeek returned a JSON body without a 'choices' field — e.g. an error-shaped payload deserialized into ChatCompletion, a content-filter/empty completion, or an API schema change.","commonSituations":"Prompts rejected by content filtering; max_tokens or stop conditions producing no choices; DeepSeek API contract changes after model/version upgrades; using an incorrect base-url pointing to a compatible-but-different API.","solutions":["Log/inspect the full ChatCompletion body (including any error or usage fields) to see why choices are absent.","Review the prompt for content that DeepSeek may refuse and adjust it.","Check deepseek API version / spring-ai-deepseek version compatibility after upgrades.","Handle the empty-generations ChatResponse defensively in application code."],"exampleFix":"// before\nChatResponse r = chatModel.call(new Prompt(msg));\nreturn r.getResults().get(0); // IndexOutOfBounds when choices null\n// after\nreturn r.getResults().isEmpty() ? Optional.empty() : Optional.of(r.getResults().get(0));","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static Optional<Generation> firstGeneration(ChatResponse r) {\n    return (r == null || r.getResults() == null) ? Optional.empty()\n            : r.getResults().stream().findFirst();\n}","tryCatchPattern":"Optional<Generation> gen = firstGeneration(chatModel.call(new Prompt(msg)));\nGeneration g = gen.orElseThrow(() -> new IllegalStateException(\"DeepSeek returned no choices for prompt\"));","preventionTips":["Never index getResults().get(0) without an emptiness check","Review prompts for content likely to be filtered","Pin and test spring-ai-deepseek against your DeepSeek API version after upgrades"],"tags":["deepseek","chat-completion","empty-choices","api-schema"],"backgroundTag":"unexpected-response-shape","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"}