{"record":{"id":"930074c551b7b8aa","repo":"microsoft/semantic-kernel","slug":"unresolved-placeholders-in-spec-join-f-930074","errorCode":null,"errorMessage":"Unresolved placeholders in spec: {', '.join(f'${{{key}}}' for key in unresolved)}","messagePattern":"Unresolved placeholders in spec: (.+?)\\}' for key in unresolved\\)\\}","errorType":"exception","errorClass":"AgentInitializationException","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/agents/open_ai/azure_assistant_agent.py","lineNumber":282,"sourceCode":"        if extras:\n            field_mapping.update(extras)\n\n        def replacer(match: re.Match[str]) -> str:\n            \"\"\"Replace the matched placeholder with the corresponding value from field_mapping.\"\"\"\n            full_key = match.group(1)  # for example, OpenAI:ApiKey\n            section, _, key = full_key.partition(\":\")\n            if section != \"AzureOpenAI\":\n                return match.group(0)\n\n            # Try short key first (ApiKey), then full (OpenAI:ApiKey)\n            return str(field_mapping.get(key) or field_mapping.get(full_key) or match.group(0))\n\n        result = pattern.sub(replacer, yaml_str)\n\n        # Safety check for unresolved placeholders\n        unresolved = pattern.findall(result)\n        if unresolved:\n            raise AgentInitializationException(\n                f\"Unresolved placeholders in spec: {', '.join(f'${{{key}}}' for key in unresolved)}\"\n            )\n\n        return result\n","sourceCodeStart":264,"sourceCodeEnd":287,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/agents/open_ai/azure_assistant_agent.py#L264-L287","documentation":"Raised by AzureAssistantAgent.resolve_placeholders() after substituting ${AzureOpenAI:Key} placeholders when one or more placeholders remain unresolvable. A placeholder is unresolved when its key is neither in the field_mapping (built from AzureOpenAISettings fields) nor in the extras dict, leaving a literal ${...} in the rendered YAML spec.","triggerScenarios":"A declarative agent YAML/spec references a placeholder like ${AzureOpenAI:SomeField} that the settings object does not expose (e.g. a typo, or a field not in the mapping such as a non-existent key), and no matching value is supplied via extras.","commonSituations":"Typos in placeholder names (${AzureOpenAI:DepoymentName}); referencing fields not in the built-in mapping (only ChatModelId, AgentId, ApiKey, ApiVersion, BaseUrl, Endpoint, TokenEndpoint are mapped); forgetting to pass needed runtime values through extras; stale spec files after a schema change.","solutions":["Inspect the unresolved keys in the error message and fix typos or remove unused placeholders from the spec.","Supply the missing value via the extras argument: resolve_placeholders(yaml, extras={'SomeField': value}).","Confirm the settings object actually has the field populated (e.g. set AZURE_OPENAI_CHAT_DEPLOYMENT_NAME for ChatModelId).","Use only the documented placeholder keys (ChatModelId, AgentId, ApiKey, ApiVersion, BaseUrl, Endpoint, TokenEndpoint)."],"exampleFix":"# before\nAzureAssistantAgent.resolve_placeholders(yaml)  # yaml has ${AzureOpenAI:OrgId} -> unresolved\n# after (remove typo'd placeholder, or supply via extras)\nAzureAssistantAgent.resolve_placeholders(yaml, extras={\"OrgId\": \"my-org\"})","handlingStrategy":"validation","validationCode":"import re\n\nSUPPORTED = {\"ChatModelId\", \"AgentId\", \"ApiKey\", \"ApiVersion\", \"BaseUrl\", \"Endpoint\", \"TokenEndpoint\"}\nplaceholders = set(re.findall(r\"\\$\\{AzureOpenAI:([^}]+)\\}\", yaml_str))\nunknown = placeholders - SUPPORTED - set(extras or {})\nif unknown:\n    raise ValueError(f\"Spec references unsupported/unsupplied placeholders: {unknown}\")\nresolved = AzureAssistantAgent.resolve_placeholders(yaml_str, settings=settings, extras=extras)","typeGuard":null,"tryCatchPattern":"from semantic_kernel.exceptions.agent_exceptions import AgentInitializationException\n\ntry:\n    resolved = AzureAssistantAgent.resolve_placeholders(yaml_str, extras=extras)\nexcept AgentInitializationException as e:\n    # e.message lists the unresolved keys\n    missing = parse_unresolved(e.args[0])\n    extras = extras or {}\n    extras.update(resolve_from_env(missing))\n    resolved = AzureAssistantAgent.resolve_placeholders(yaml_str, extras=extras)","preventionTips":["Maintain a list of supported placeholder keys and lint spec files against it.","Pass all runtime-only values through extras rather than inventing settings fields.","Unit-test spec rendering in CI to catch unresolved placeholders early."],"tags":["azure-openai","declarative-spec","semantic-kernel","agents","placeholders","validation"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}