{"record":{"id":"c58ef66075f649b2","repo":"microsoft/semantic-kernel","slug":"functionchoicebehavior-filters-must-not-be-empty-c58ef6","errorCode":null,"errorMessage":"FunctionChoiceBehavior filters must not be empty. Provide at least one filter key from {sorted(valid_filter_keys)}, or omit filters entirely to include all kernel functions.","messagePattern":"FunctionChoiceBehavior filters must not be empty\\. Provide at least one filter key from (.+?), or omit filters entirely to include all kernel functions\\.","errorType":"exception","errorClass":"AgentInvokeException","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/agents/open_ai/assistant_thread_actions.py","lineNumber":900,"sourceCode":"            raise AgentInvokeException(\n                f\"FunctionChoiceBehavior with type '{function_choice_behavior.type_}' is not supported for agent \"\n                \"invocations. Use FunctionChoiceBehavior.Auto(filters=...) to control which kernel functions \"\n                \"are available.\"\n            )\n        if not function_choice_behavior.auto_invoke_kernel_functions:\n            raise AgentInvokeException(\n                \"FunctionChoiceBehavior.Auto(auto_invoke=False) is not supported for agent invocations. \"\n                \"The agent run loop manages tool invocation; disabling auto_invoke is not compatible.\"\n            )\n        valid_filter_keys: set[str] = {\n            \"excluded_plugins\",\n            \"included_plugins\",\n            \"excluded_functions\",\n            \"included_functions\",\n        }\n        if function_choice_behavior.filters is not None:\n            if not function_choice_behavior.filters:\n                raise AgentInvokeException(\n                    \"FunctionChoiceBehavior filters must not be empty. Provide at least one filter key \"\n                    f\"from {sorted(valid_filter_keys)}, or omit filters entirely to include all \"\n                    \"kernel functions.\"\n                )\n            unknown_keys = {str(k) for k in function_choice_behavior.filters} - valid_filter_keys\n            if unknown_keys:\n                raise AgentInvokeException(\n                    f\"Unknown filter key(s): {sorted(unknown_keys)}. \"\n                    f\"Valid filter keys are: {sorted(valid_filter_keys)}.\"\n                )\n\n    @classmethod\n    def _get_tools(\n        cls: type[_T],\n        agent: \"OpenAIAssistantAgent\",\n        kernel: \"Kernel\",\n        tools_override: \"list[AssistantToolParam] | None\" = None,\n        function_choice_behavior: FunctionChoiceBehavior | None = None,","sourceCodeStart":882,"sourceCodeEnd":918,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/agents/open_ai/assistant_thread_actions.py#L882-L918","documentation":"If you supply a filters object to FunctionChoiceBehavior for an agent invocation, it must not be empty/falsy. An empty filters value is rejected because it carries no information — you either provide at least one recognized key (excluded_plugins, included_plugins, excluded_functions, included_functions) or omit filters to include all kernel functions.","triggerScenarios":"Constructing FunctionChoiceBehavior.Auto(filters={}) (empty dict/None-valued filter object) and passing it to an assistant agent invoke / thread-action call.","commonSituations":"Programmatically building filters that end up empty after conditionally dropping keys; deserializing config that yields an empty filters map; misunderstanding that an empty filter means 'no restriction' rather than 'include nothing'.","solutions":["Provide at least one recognized filter key, e.g. filters={'included_functions': ['x']}.","If you want all kernel functions available, omit filters entirely (pass None / do not set it).","Validate the filters dict is non-empty before constructing the behavior in dynamic code."],"exampleFix":"// before\nfcb = FunctionChoiceBehavior.Auto(filters={})\nawait assistant.invoke(kernel=kernel, function_choice_behavior=fcb, thread_id=tid)\n\n// after\nfcb = FunctionChoiceBehavior.Auto()  # include all kernel functions\nawait assistant.invoke(kernel=kernel, function_choice_behavior=fcb, thread_id=tid)","handlingStrategy":"validation","validationCode":"VALID = {\"excluded_plugins\", \"included_plugins\", \"excluded_functions\", \"included_functions\"}\n\ndef filters_ok(fcb) -> bool:\n    return fcb is None or fcb.filters is None or (isinstance(fcb.filters, dict) and len(fcb.filters) > 0 and set(fcb.filters) <= VALID)","typeGuard":"VALID = {\"excluded_plugins\", \"included_plugins\", \"excluded_functions\", \"included_functions\"}\n\ndef is_valid_filters(fcb) -> bool:\n    if fcb is None or getattr(fcb, 'filters', None) is None:\n        return True\n    f = fcb.filters\n    return bool(f) and set(f) <= VALID","tryCatchPattern":null,"preventionTips":["Omit filters to include all functions, or supply at least one recognized key.","When building filters dynamically, assert non-empty before constructing the behavior."],"tags":["openai","assistant","function-choice-behavior","filters","validation"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}