{"record":{"id":"410336d9841039d5","repo":"microsoft/semantic-kernel","slug":"openapi-tool-spec-id-requires-a-description","errorCode":null,"errorMessage":"OpenAPI tool '{spec.id}' requires a 'description'.","messagePattern":"OpenAPI tool '(.+?)' requires a 'description'\\.","errorType":"validation","errorClass":"AgentInitializationException","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/agents/azure_ai/azure_ai_agent.py","lineNumber":204,"sourceCode":"    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,\n        auth=auth,\n        default_parameters=opts.get(\"default_parameters\"),","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/agents/azure_ai/azure_ai_agent.py#L186-L222","documentation":"Raised when an openapi tool spec has an id but no description. The Azure AI service requires a description for each tool to inform the model when to invoke it.","triggerScenarios":"Declarative spec includes an openapi tool with an id but missing or empty description field.","commonSituations":"Developer relies on the OpenAPI spec's own description and omits the tool-level description; description field templated from an unset variable.","solutions":["Add a concise, non-empty description to the openapi tool entry explaining what the API does.","If the description is generated dynamically, ensure it resolves to a non-empty string before building the agent."],"exampleFix":"// before\ntools:\n  - type: openapi\n    id: weatherApi\n    options:\n      specification: '{...}'\n\n// after\ntools:\n  - type: openapi\n    id: weatherApi\n    description: Returns current weather for a city.\n    options:\n      specification: '{...}'","handlingStrategy":"validation","validationCode":"def ensure_openapi_description(tool_spec: dict) -> None:\n    if not tool_spec.get(\"description\"):\n        raise ValueError(\"openapi tool requires non-empty 'description'\")","typeGuard":"def has_openapi_description(tool_spec: dict) -> bool:\n    return bool(tool_spec.get(\"description\"))","tryCatchPattern":null,"preventionTips":["Require description in your spec schema for every openapi tool.","Write the description for the model: describe when to call the API, not its internals."],"tags":["azure-ai-agent","declarative-spec","openapi","configuration"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}