microsoft/semantic-kernel · error · AgentInitializationException

Unresolved placeholders in spec: {', '.join(f'${{{key}}}' fo

Error message

Unresolved placeholders in spec: {', '.join(f'${{{key}}}' for key in unresolved)}

What it means

Raised by AzureAIAgent.resolve_placeholders when, after substitution, ${...} placeholders remain in the YAML. Each placeholder must resolve via the AzureAI settings field mapping or the extras dict; any leftover means a referenced value was not provided. Surfaced as AgentInitializationException listing the unresolved keys.

Source

Thrown at python/semantic_kernel/agents/azure_ai/azure_ai_agent.py:627

        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, AzureAI:AzureAISearchConnectionId
            section, _, key = full_key.partition(":")
            if section != "AzureAI":
                return match.group(0)

            # Try short key first (AzureAISearchConnectionId), then full (AzureAI:AzureAISearchConnectionId)
            return str(field_mapping.get(key) or field_mapping.get(full_key) or match.group(0))

        result = pattern.sub(replacer, yaml_str)

        # Safety check for unresolved placeholders
        unresolved = pattern.findall(result)
        if unresolved:
            raise AgentInitializationException(
                f"Unresolved placeholders in spec: {', '.join(f'${{{key}}}' for key in unresolved)}"
            )

        return result

    # endregion

    # region Invocation Methods

    @trace_agent_get_response
    @override
    async def get_response(
        self,
        messages: str | ChatMessageContent | list[str | ChatMessageContent] | None = None,
        *,
        thread: AgentThread | None = None,
        arguments: KernelArguments | None = None,
        kernel: Kernel | None = None,

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Set the required AzureAIAgentSettings env vars (model_deployment_name, endpoint, etc.) so each referenced field is non-empty.
  2. Pass any custom values via the extras dict keyed by the short name used in the placeholder.
  3. Match the placeholder key exactly (case-sensitive) to the field_mapping keys.
  4. Ensure the placeholder uses the AzureAI: section prefix.

Example fix

// before
yaml: "model: ${AzureAI:ChatModelId}"  // model_deployment_name unset -> unresolved
// after
export AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME=gpt-4o-deployment
# or pass extras:
resolve_placeholders(yaml, extras={"ChatModelId": "gpt-4o-deployment"})
Defensive patterns

Strategy: validation

Validate before calling

import re
_ALLOWED = {'ChatModelId','Endpoint','AgentId','BingConnectionId','AzureAISearchConnectionId','AzureAISearchIndexName'}
def validate_placeholders(yaml_str, extras=None):
    keys = set(re.findall(r'\$\{AzureAI:([^}]+)\}', yaml_str))
    missing = {k for k in keys if k not in _ALLOWED and (not extras or k not in extras)}
    if missing:
        raise ValueError(f'Unresolved placeholders need values or extras: {missing}')
    return yaml_str

Type guard

def all_placeholders_resolvable(yaml_str, extras=None) -> bool:
    keys = set(re.findall(r'\$\{AzureAI:([^}]+)\}', yaml_str))
    return all(k in _ALLOWED or (extras and k in extras) for k in keys)

Try / catch

try:
    AzureAIAgent.resolve_placeholders(yaml, settings=settings, extras=extras)
except AgentInitializationException as e:
    if 'Unresolved placeholders' in str(e):
        log.error('Provide env vars or extras for the listed keys')
    raise

Prevention

When it happens

Trigger: Spec references ${AzureAI:SomeKey} where SomeKey is not one of ChatModelId, Endpoint, AgentId, BingConnectionId, AzureAISearchConnectionId, AzureAISearchIndexName and is not in extras; the corresponding settings field is empty/None so the replacer falls through to the raw placeholder; a typo in the key.

Common situations: Forgetting to set AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME so ChatModelId is None; referencing a custom value not supplied via extras; placeholder key casing mismatch (e.g. chatmodelid vs ChatModelId); settings loaded from env that was empty.

Related errors


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