{"record":{"id":"67fe1e85918160cf","repo":"microsoft/semantic-kernel","slug":"function-id-is-required-for-function-tools","errorCode":null,"errorMessage":"Function ID is required for function tools.","messagePattern":"Function ID is required for function tools\\.","errorType":"validation","errorClass":"AgentInitializationException","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/agents/azure_ai/azure_ai_agent.py","lineNumber":184,"sourceCode":"\n@_register_tool(\"file_search\")\ndef _file_search(spec: ToolSpec) -> FileSearchTool:\n    vector_store_ids = spec.options.get(\"vector_store_ids\")\n    if not vector_store_ids or not isinstance(vector_store_ids, list) or not vector_store_ids[0]:\n        raise AgentInitializationException(f\"Missing or malformed 'vector_store_ids' in: {spec}\")\n    return FileSearchTool(vector_store_ids=vector_store_ids)\n\n\n@_register_tool(\"function\")\ndef _function(spec: ToolSpec, kernel: \"Kernel\") -> ToolDefinition:\n    def parse_fqn(fqn: str) -> tuple[str, str]:\n        parts = fqn.split(\".\")\n        if len(parts) != 2:\n            raise AgentInitializationException(f\"Function `{fqn}` must be in the form `pluginName.functionName`.\")\n        return parts[0], parts[1]\n\n    if not spec.id:\n        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).\")","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/agents/azure_ai/azure_ai_agent.py#L166-L202","documentation":"Raised when a function tool spec has no id. The id is the plugin.function lookup key used to resolve the tool against the Kernel.","triggerScenarios":"Declarative spec includes a function tool entry without an id field, or id is an empty string.","commonSituations":"Developer assumes the function is inferred from options; spec template leaves id blank.","solutions":["Add a non-empty id in pluginName.functionName format to the function tool spec.","Validate that every function-typed tool entry has a populated id before building the agent."],"exampleFix":"// before\ntools:\n  - type: function\n    description: Does a thing\n\n// after\ntools:\n  - type: function\n    id: MyPlugin.MyFunc\n    description: Does a thing","handlingStrategy":"validation","validationCode":"def ensure_function_id(tool_spec: dict) -> None:\n    if not tool_spec.get(\"id\"):\n        raise ValueError(\"function tool requires non-empty 'id'\")","typeGuard":"def has_function_id(tool_spec: dict) -> bool:\n    return bool(tool_spec.get(\"id\"))","tryCatchPattern":null,"preventionTips":["Require id in your spec schema for every function tool.","Reject function-tool entries without id during CI spec validation."],"tags":["azure-ai-agent","declarative-spec","function-tool","configuration"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}