microsoft/semantic-kernel · error · ServiceInvalidExecutionSettingsError

When used with number_of_responses, best_of controls the num

Error message

When used with number_of_responses, best_of controls the number of candidate completions and n specifies how many to return, therefore best_of must be greater than number_of_responses.

What it means

OpenAI's text completion API requires that the best_of parameter (number of candidate completions generated server-side) be >= n / number_of_responses (how many are returned). The pydantic model_validator in OpenAITextPromptExecutionSettings checks this after instantiation and raises ServiceInvalidExecutionSettingsError if best_of < number_of_responses. Both fields can come from the model attributes or from extension_data.

Source

Thrown at python/semantic_kernel/connectors/ai/open_ai/prompt_execution_settings/open_ai_prompt_execution_settings.py:51

class OpenAITextPromptExecutionSettings(OpenAIPromptExecutionSettings):
    """Specific settings for the completions endpoint."""

    prompt: Annotated[
        str | None, Field(description="Do not set this manually. It is set by the service based on the text content.")
    ] = None
    best_of: Annotated[int | None, Field(ge=1)] = None
    echo: bool = False
    logprobs: Annotated[int | None, Field(ge=0, le=5)] = None
    suffix: str | None = None

    @model_validator(mode="after")
    def check_best_of_and_n(self) -> "OpenAITextPromptExecutionSettings":
        """Check that the best_of parameter is not greater than the number_of_responses parameter."""
        best_of = self.best_of or self.extension_data.get("best_of")
        number_of_responses = self.number_of_responses or self.extension_data.get("number_of_responses")

        if best_of is not None and number_of_responses is not None and best_of < number_of_responses:
            raise ServiceInvalidExecutionSettingsError(
                "When used with number_of_responses, best_of controls the number of candidate completions and n specifies how many to return, therefore best_of must be greater than number_of_responses."  # noqa: E501
            )

        return self


class OpenAIChatPromptExecutionSettings(OpenAIPromptExecutionSettings):
    """Specific settings for the Chat Completion endpoint."""

    response_format: (
        dict[Literal["type"], Literal["text", "json_object"]] | dict[str, Any] | type[BaseModel] | type | None
    ) = None
    function_call: str | None = None
    functions: list[dict[str, Any]] | None = None
    messages: Annotated[
        list[dict[str, Any]] | None, Field(description="Do not set this manually. It is set by the service.")
    ] = None
    parallel_tool_calls: bool | None = None

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Set best_of >= number_of_responses (e.g. best_of=5, number_of_responses=3).
  2. Remove best_of entirely if you don't need server-side candidate filtering — OpenAI defaults best_of to n.
  3. Audit your settings dict before instantiation to ensure the constraint holds.

Example fix

// before
settings = OpenAITextPromptExecutionSettings(best_of=2, number_of_responses=5)
// after
settings = OpenAITextPromptExecutionSettings(best_of=5, number_of_responses=5)
Defensive patterns

Strategy: validation

Validate before calling

def validate_best_of_and_n(best_of: int | None, number_of_responses: int | None) -> None:
    if best_of is not None and number_of_responses is not None:
        if best_of < number_of_responses:
            raise ValueError(
                f'best_of ({best_of}) must be >= number_of_responses ({number_of_responses})'
            )

Type guard

def are_text_completion_settings_valid(best_of, number_of_responses) -> bool:
    if best_of is None or number_of_responses is None:
        return True
    return best_of >= number_of_responses

Try / catch

from semantic_kernel.exceptions import ServiceInvalidExecutionSettingsError

try:
    settings = OpenAITextPromptExecutionSettings(best_of=b, number_of_responses=n)
except ServiceInvalidExecutionSettingsError as e:
    b = max(b, n)  # fix by raising best_of
    settings = OpenAITextPromptExecutionSettings(best_of=b, number_of_responses=n)

Prevention

When it happens

Trigger: Setting OpenAITextPromptExecutionSettings(best_of=2, number_of_responses=5) — or passing them via extension_data with best_of < number_of_responses. The validator runs on any pydantic model validation (instantiation, copy, re-validation).

Common situations: Copy-pasting settings from a chat completion config (where n/best_of semantics differ); setting number_of_responses high for variety but forgetting to raise best_of proportionally; reading values from a config file where best_of and n are independently set.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/c84b8a9cc658a121. Report an issue: GitHub.