PrefectHQ/fastmcp · error · ValueError

No response for completion

Error message

No response for completion

What it means

After receiving a ChatCompletion from OpenAI, this converter requires at least one choice. If chat_completion.choices is an empty list, it cannot construct a CreateMessageResult and raises this ValueError.

Source

Thrown at fastmcp_slim/fastmcp/client/sampling/handlers/openai.py:392

                    )
                openai_messages.append(
                    ChatCompletionUserMessageParam(
                        role="user",
                        content=[_audio_content_to_openai_part(content)],
                    )
                )
                continue

            raise ValueError(f"Unsupported content type: {type(content)}")

        return openai_messages

    @staticmethod
    def _chat_completion_to_create_message_result(
        chat_completion: ChatCompletion,
    ) -> CreateMessageResult:
        if len(chat_completion.choices) == 0:
            raise ValueError("No response for completion")

        first_choice = chat_completion.choices[0]

        if content := first_choice.message.content:
            return CreateMessageResult(
                content=TextContent(type="text", text=content),
                role="assistant",
                model=chat_completion.model,
            )

        raise ValueError("No content in response from completion")

    def _select_model_from_preferences(
        self, model_preferences: ModelPreferences | str | list[str] | None
    ) -> ChatModel:
        for model_option in self._iter_models_from_preferences(model_preferences):
            if model_option in get_args(ChatModel):
                chosen_model: ChatModel = model_option  # type: ignore[assignment]  # ty:ignore[invalid-assignment]

View on GitHub (pinned to 1f02114297)

Solutions

  1. Log chat_completion.model, id, and finish info to identify why the API returned no choices, then retry the sampling request.
  2. Check the OpenAI account/org for content-filter or moderation flags that may empty the response.
  3. Catch the ValueError and fall back to another sampling handler or provider.
  4. Add a pre-check: if not completion.choices: retry or raise a clearer domain error before calling the handler.

Example fix

// before
result = await sampling_handler(messages, params)
// after
try:
    result = await sampling_handler(messages, params)
except ValueError as e:
    if 'No response for completion' in str(e):
        result = await sampling_handler(messages, params)  # retry once
    else:
        raise
Defensive patterns

Strategy: retry

Validate before calling

def has_choices(completion) -> bool:
    return bool(getattr(completion, 'choices', None))

Type guard

def is_usable_completion(completion) -> bool:
    return len(getattr(completion, 'choices', [])) > 0

Try / catch

try:
    result = await sampling_handler(messages, params)
except ValueError as e:
    if str(e) == 'No response for completion':
        result = await sampling_handler(messages, params)  # retry with backoff
    else:
        raise

Prevention

When it happens

Trigger: OpenAI returns a ChatCompletion with zero choices (typically with finish_reason set or a content filter / error payload that still parses as a completion) and it is passed to _chat_completion_to_create_message_result.

Common situations: Content filter blocking the entire response; API returning an empty choices array due to service degradation; n=0 configuration upstream; mocked/test clients returning empty completions.

Related errors


AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29). Data as JSON: /api/errors/bf114da97ed14d43. Report an issue: GitHub.