{"record":{"id":"f606944258e2e108","repo":"microsoft/semantic-kernel","slug":"openapi-tool-requires-a-non-empty-id-used-as-na","errorCode":null,"errorMessage":"OpenAPI tool requires a non-empty 'id' (used as name).","messagePattern":"OpenAPI tool requires a non-empty 'id' \\(used as name\\)\\.","errorType":"validation","errorClass":"AgentInitializationException","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/agents/azure_ai/azure_ai_agent.py","lineNumber":202,"sourceCode":"        raise AgentInitializationException(\"Function ID is required for function tools.\")\n    plugin_name, function_name = parse_fqn(spec.id)\n    funcs = kernel.get_list_of_function_metadata_filters({\"included_functions\": f\"{plugin_name}-{function_name}\"})\n\n    match len(funcs):\n        case 0:\n            raise AgentInitializationException(f\"Function `{spec.id}` not found in kernel.\")\n        case 1:\n            return kernel_function_metadata_to_function_call_format(funcs[0])  # type: ignore[return-value]\n        case _:\n            raise AgentInitializationException(f\"Multiple definitions found for `{spec.id}`. Please remove duplicates.\")\n\n\n@_register_tool(\"openapi\")\ndef _openapi(spec: ToolSpec) -> OpenApiTool:\n    opts = spec.options or {}\n\n    if not spec.id:\n        raise AgentInitializationException(\"OpenAPI tool requires a non-empty 'id' (used as name).\")\n    if not spec.description:\n        raise AgentInitializationException(f\"OpenAPI tool '{spec.id}' requires a 'description'.\")\n\n    raw_spec = opts.get(\"specification\")\n    if not raw_spec:\n        raise AgentInitializationException(f\"OpenAPI tool '{spec.id}' is missing required 'specification' field.\")\n\n    try:\n        parsed_spec = json.loads(raw_spec) if isinstance(raw_spec, str) else raw_spec\n    except json.JSONDecodeError as e:\n        raise AgentInitializationException(f\"Invalid JSON in OpenAPI 'specification' field: {e}\") from e\n\n    auth = opts.get(\"auth\", OpenApiAnonymousAuthDetails())\n\n    return OpenApiTool(\n        name=spec.id,\n        description=spec.description,\n        spec=parsed_spec,","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/agents/azure_ai/azure_ai_agent.py#L184-L220","documentation":"Raised when an openapi tool spec has no id. The id is used as the tool's name when registering the OpenAPI spec with the Azure AI agent, so it must be a non-empty string.","triggerScenarios":"Declarative spec includes an openapi tool entry without an id field or with an empty id string.","commonSituations":"Developer assumes the id is derived from the OpenAPI spec's title; spec template leaves id blank; id templated from an unset variable.","solutions":["Add a non-empty, unique id to the openapi tool entry; it becomes the tool name.","Ensure the id does not collide with other tool ids in the same spec."],"exampleFix":"// before\ntools:\n  - type: openapi\n    description: Weather API\n    options:\n      specification: '{...}'\n\n// after\ntools:\n  - type: openapi\n    id: weatherApi\n    description: Weather API\n    options:\n      specification: '{...}'","handlingStrategy":"validation","validationCode":"def ensure_openapi_id(tool_spec: dict) -> None:\n    if not tool_spec.get(\"id\"):\n        raise ValueError(\"openapi tool requires non-empty 'id'\")","typeGuard":"def has_openapi_id(tool_spec: dict) -> bool:\n    return bool(tool_spec.get(\"id\"))","tryCatchPattern":null,"preventionTips":["Require id in your spec schema for every openapi tool.","Use a unique, descriptive id since it becomes the tool name."],"tags":["azure-ai-agent","declarative-spec","openapi","configuration"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}