microsoft/semantic-kernel · error · AgentInitializationException

Expected OpenAISettings, got {type(settings).__name__}

Error message

Expected OpenAISettings, got {type(settings).__name__}

What it means

Raised by OpenAIAssistantAgent.resolve_placeholders() when the settings argument, after defaulting, is not an instance of OpenAISettings. resolve_placeholders reads chat_model_id/agent_id/api_key attributes via getattr; a wrong settings type would silently yield None for those fields, so the guard rejects it up front. If settings is None the method constructs a default OpenAISettings() first.

Source

Thrown at python/semantic_kernel/agents/open_ai/openai_assistant_agent.py:568

    def resolve_placeholders(
        cls: type[_T],
        yaml_str: str,
        settings: "KernelBaseSettings | None" = None,
        extras: dict[str, Any] | None = None,
    ) -> str:
        """Substitute ${OpenAI:Key} placeholders with fields from OpenAIAgentSettings and extras."""
        import re

        pattern = re.compile(r"\$\{([^}]+)\}")

        # Build the mapping only if settings is provided and valid
        field_mapping: dict[str, Any] = {}

        if settings is None:
            settings = OpenAISettings()

        if not isinstance(settings, OpenAISettings):
            raise AgentInitializationException(f"Expected OpenAISettings, got {type(settings).__name__}")

        field_mapping.update({
            "ChatModelId": cls._get_setting(getattr(settings, "chat_model_id", None)),
            "AgentId": cls._get_setting(getattr(settings, "agent_id", None)),
            "ApiKey": cls._get_setting(getattr(settings, "api_key", None)),
        })

        if extras:
            field_mapping.update(extras)

        def replacer(match: re.Match[str]) -> str:
            """Replace the matched placeholder with the corresponding value from field_mapping."""
            full_key = match.group(1)  # for example, OpenAI:ApiKey
            section, _, key = full_key.partition(":")
            if section != "OpenAI":
                return match.group(0)

            # Try short key first (ApiKey), then full (OpenAI:ApiKey)

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Pass an OpenAISettings instance (or None to let it default).
  2. If you hold an AzureOpenAISettings, convert/map it into an OpenAISettings before calling.
  3. Type-check settings before the call: assert isinstance(settings, OpenAISettings) or settings is None.

Example fix

# before
resolve_placeholders(yaml_str, settings=azure_settings)

# after
from semantic_kernel.connectors.ai.open_ai.settings.open_ai_settings import OpenAISettings
resolve_placeholders(yaml_str, settings=OpenAISettings(api_key=azure_settings.api_key, chat_model_id=azure_settings.chat_model_id))
Defensive patterns

Strategy: type-guard

Validate before calling

from semantic_kernel.connectors.ai.open_ai.settings.open_ai_settings import OpenAISettings
assert settings is None or isinstance(settings, OpenAISettings), 'settings must be OpenAISettings or None'

Type guard

from semantic_kernel.connectors.ai.open_ai.settings.open_ai_settings import OpenAISettings
def is_openai_settings(s) -> bool:
    return s is None or isinstance(s, OpenAISettings)

Try / catch

from semantic_kernel.exceptions.agent_exceptions import AgentInitializationException
try:
    resolve_placeholders(yaml_str, settings=settings)
except AgentInitializationException as e:
    if 'Expected OpenAISettings' in str(e):
        resolve_placeholders(yaml_str, settings=OpenAISettings())

Prevention

When it happens

Trigger: Passing a KernelBaseSettings subclass that is not OpenAISettings (e.g. AzureOpenAISettings, a custom settings object, or a plain dict) to resolve_placeholders; a factory handing the wrong settings instance.

Common situations: Reusing an Azure OpenAI settings object against the non-Azure assistant agent; custom settings class that mirrors but does not subclass OpenAISettings; refactoring connectors and passing mismatched settings.

Related errors


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