{"record":{"id":"026515bb32b43f8e","repo":"microsoft/semantic-kernel","slug":"function-fqn-must-be-in-the-form-pluginname-f","errorCode":null,"errorMessage":"Function `{fqn}` must be in the form `pluginName.functionName`.","messagePattern":"Function `(.+?)` must be in the form `pluginName\\.functionName`\\.","errorType":"validation","errorClass":"AgentInitializationException","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/agents/azure_ai/azure_ai_agent.py","lineNumber":180,"sourceCode":"def _code_interpreter(spec: ToolSpec) -> CodeInterpreterTool:\n    file_ids = spec.options.get(\"file_ids\")\n    return CodeInterpreterTool(file_ids=file_ids) if file_ids else CodeInterpreterTool()\n\n\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:","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/agents/azure_ai/azure_ai_agent.py#L162-L198","documentation":"Raised when a function tool's id (fully-qualified name) does not split into exactly two parts on '.'. The declarative builder expects the form pluginName.functionName and cannot resolve malformed names.","triggerScenarios":"Setting a function tool id to 'functionName' (no plugin), 'a.b.c', or any value without exactly one dot separator.","commonSituations":"Developer uses the dash-separated format ('Plugin-Func') valid for filters but not here; forgets the plugin prefix; includes extra dotted segments.","solutions":["Format the function tool id as pluginName.functionName with exactly one dot.","Confirm the plugin name and function name match those registered on the Kernel.","If the function lives at the top level, place it in a named plugin first."],"exampleFix":"// before\ntools:\n  - type: function\n    id: MyFunc\n# or id: A-B-C\n\n// after\ntools:\n  - type: function\n    id: MyPlugin.MyFunc","handlingStrategy":"validation","validationCode":"def validate_function_id(tool_id: str) -> None:\n    parts = tool_id.split(\".\")\n    if len(parts) != 2:\n        raise ValueError(f\"id '{tool_id}' must be 'pluginName.functionName'\")","typeGuard":"def is_well_formed_fqn(tool_id: str) -> bool:\n    parts = tool_id.split(\".\")\n    return len(parts) == 2 and all(parts)","tryCatchPattern":null,"preventionTips":["Author function tool ids with exactly one dot: pluginName.functionName.","Add a lint step that checks every function-tool id has exactly one '.' separator."],"tags":["azure-ai-agent","declarative-spec","function-tool","naming"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}