{"record":{"id":"a0f689e04866db62","repo":"microsoft/semantic-kernel","slug":"orchestration-must-be-subclassed-with-two-type-par","errorCode":null,"errorMessage":"Orchestration must be subclassed with two type parameters.","messagePattern":"Orchestration must be subclassed with two type parameters\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/agents/orchestration/orchestration_base.py","lineNumber":174,"sourceCode":"        \"\"\"\n        if all([self.t_in is not None, self.t_out is not None]):\n            return\n\n        try:\n            args = self.__orig_class__.__args__  # type: ignore[attr-defined]\n            if len(args) == 1:\n                self.t_in = args[0]\n                self.t_out = DefaultTypeAlias  # type: ignore[assignment]\n            elif len(args) == 2:\n                self.t_in = args[0]\n                self.t_out = args[1]\n            else:\n                raise TypeError(\"Orchestration must have two type parameters.\")\n        except AttributeError:\n            args = get_args(self.__orig_bases__[0])  # type: ignore[attr-defined]\n\n            if len(args) != 2:\n                raise TypeError(\"Orchestration must be subclassed with two type parameters.\")\n            self.t_in = args[0] if isinstance(args[0], type) else getattr(args[0], \"__default__\", None)  # type: ignore[assignment]\n            self.t_out = args[1] if isinstance(args[1], type) else getattr(args[1], \"__default__\", None)  # type: ignore[assignment]\n\n        if any([self.t_in is None, self.t_out is None]):\n            raise TypeError(\"Orchestration must have concrete types for all type parameters.\")\n\n    async def invoke(\n        self,\n        task: str | DefaultTypeAlias | TIn,\n        runtime: CoreRuntime,\n    ) -> OrchestrationResult[TOut]:\n        \"\"\"Invoke the multi-agent orchestration.\n\n        This method is non-blocking and will return immediately.\n        To wait for the result, use the `get` method of the `OrchestrationResult` object.\n\n        Args:\n            task (str, DefaultTypeAlias, TIn): The task to be executed by the agents.","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/agents/orchestration/orchestration_base.py#L156-L192","documentation":"When __orig_class__ is absent (i.e. you subclassed OrchestrationBase rather than subscripting an instance), _set_types falls back to __orig_bases__[0] and reads its type args. It requires exactly two args there; anything else (zero, one, three) is rejected. This is the path for declarative subclassing.","triggerScenarios":"Declaring `class MyOrchestration(OrchestrationBase):` (no type params) or with a count other than two, then instantiating it directly so __orig_class__ is not set and the __orig_bases__ branch runs.","commonSituations":"Subclassing OrchestrationBase without specifying TypeVars, e.g. `class Foo(OrchestrationBase): pass; Foo(members)`. Subclassing with a single TypeVar. A subclass that loses its generic parameterization.","solutions":["Subclass with exactly two type parameters: `class MyOrchestration(OrchestrationBase[str, str]): ...`.","If using custom TypeVars, provide both: `class MyOrchestration(OrchestrationBase[TIn, TOut]): ...`.","Prefer subscripting at instantiation (`OrchestrationBase[str, str](...)`) if you don't need a named subclass."],"exampleFix":"// before\nclass MyOrchestration(OrchestrationBase):  # no type params\n    pass\n\nMyOrchestration(members)  # raises 'must be subclassed with two type parameters'\n\n// after\nclass MyOrchestration(OrchestrationBase[str, str]):\n    pass\n\nMyOrchestration(members)","handlingStrategy":"type-guard","validationCode":"# Subclass with exactly two type parameters\nclass MyOrchestration(OrchestrationBase[str, str]):\n    pass\n\norch = MyOrchestration(members)","typeGuard":"from typing import get_args\n\ndef subclass_has_two_params(cls) -> bool:\n    bases = getattr(cls, \"__orig_bases__\", ())\n    if not bases:\n        return False\n    return len(get_args(bases[0])) == 2","tryCatchPattern":null,"preventionTips":["When subclassing OrchestrationBase, always provide two type parameters.","Prefer subscripting at instantiation if you don't need a named subclass.","Keep custom TypeVar count on the base to exactly two."],"tags":["semantic-kernel","orchestration","generics","type-parameters","subclassing"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}