{"record":{"id":"0bf71a46b1ad0326","repo":"microsoft/semantic-kernel","slug":"orchestration-must-have-concrete-types-for-all-typ","errorCode":null,"errorMessage":"Orchestration must have concrete types for all type parameters.","messagePattern":"Orchestration must have concrete types for all type parameters\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/agents/orchestration/orchestration_base.py","lineNumber":179,"sourceCode":"            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.\n            runtime (CoreRuntime): The runtime environment for the agents.\n        \"\"\"\n        self._set_types()\n\n        orchestration_result = OrchestrationResult[self.t_out]()  # type: ignore[name-defined]","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/agents/orchestration/orchestration_base.py#L161-L197","documentation":"After resolving type parameters (from either __orig_class__ or __orig_bases__), _set_types requires both t_in and t_out to be concrete. If either resolves to None — e.g. a TypeVar with no default that was never bound — the orchestration cannot (de)serialize input/output and is rejected.","triggerScenarios":"Subclassing with TypeVars that have no default and not binding them, so `getattr(arg, '__default__', None)` returns None for t_in or t_out. Also when a custom TypeVar's __default__ is None.","commonSituations":"Defining `T = TypeVar('T')` (no default) and subclassing `OrchestrationBase[T, T_out_unbound]`. Using Python <3.12 where TypeVar defaults aren't supported, leaving a param unbound. A subclass whose base args include an unresolved TypeVar.","solutions":["Bind both parameters to concrete types: subclass as `OrchestrationBase[str, str]` or instantiate `MyOrchestration[str, str](...)`.","Give your TypeVars defaults (Python 3.12+): `T = TypeVar('T', default=str)`.","Ensure both base-class args are real types, not unresolved TypeVars with no default."],"exampleFix":"// before\nT = TypeVar('T')  # no default\nclass MyOrch(OrchestrationBase[T, T]):  # T unbound at instantiate -> raises\n    pass\nMyOrch(members)\n\n// after\nclass MyOrch(OrchestrationBase[str, str]):\n    pass\nMyOrch(members)","handlingStrategy":"type-guard","validationCode":"# Bind both parameters to concrete types\nclass MyOrch(OrchestrationBase[str, str]):\n    pass\nMyOrch(members)\n# Or, on Python 3.12+, give TypeVars defaults:\n#   T = TypeVar('T', default=str)","typeGuard":"from typing import get_args\n\ndef params_are_concrete(cls) -> bool:\n    bases = getattr(cls, \"__orig_bases__\", ())\n    if not bases:\n        return False\n    return all(isinstance(a, type) for a in get_args(bases[0]))","tryCatchPattern":null,"preventionTips":["Use concrete types (not bare TypeVars) when subclassing or subscripting.","On Python 3.12+, set TypeVar defaults so unbound params resolve to a type.","Validate that both t_in and t_out resolve to real types before invoking."],"tags":["semantic-kernel","orchestration","generics","type-parameters","configuration"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}