{"record":{"id":"cfca59a5ac897ff2","repo":"deepset-ai/haystack","slug":"set-input-types-set-input-type-cannot-override","errorCode":null,"errorMessage":"set_input_types()/set_input_type() cannot override the parameters of the 'run' method","messagePattern":"set_input_types\\(\\)/set_input_type\\(\\) cannot override the parameters of the 'run' method","errorType":"exception","errorClass":"ComponentError","httpStatus":null,"severity":"error","filePath":"haystack/core/component/component.py","lineNumber":254,"sourceCode":"            run_signature = inspect.signature(method)\n            # Resolves the annotations of components using postponed evaluation of annotations, where they are stored\n            # as strings.\n            param_types = _resolve_parameter_types(method)\n\n            for param_name, param_info in run_signature.parameters.items():\n                if param_name == \"self\" or param_info.kind in (Parameter.VAR_POSITIONAL, Parameter.VAR_KEYWORD):\n                    continue\n\n                socket_kwargs = {\"name\": param_name, \"type\": param_types[param_name]}\n                if param_info.default != Parameter.empty:\n                    socket_kwargs[\"default_value\"] = param_info.default\n\n                new_socket = InputSocket(**socket_kwargs)\n\n                # Also ensure that new sockets don't override existing ones.\n                existing_socket = sockets.get(param_name)\n                if existing_socket is not None and existing_socket != new_socket:\n                    raise ComponentError(\n                        \"set_input_types()/set_input_type() cannot override the parameters of the 'run' method\"\n                    )\n\n                sockets[param_name] = new_socket\n\n            return run_signature\n\n        # Create the sockets if set_input_types() wasn't called in the constructor.\n        if not hasattr(instance, \"__haystack_input__\"):\n            instance.__haystack_input__ = Sockets(instance, {}, InputSocket)\n\n        inner(getattr(component_cls, \"run\"), instance.__haystack_input__)  # noqa: B009\n\n        # Ensure that the sockets are the same for the async method, if it exists.\n        async_run = getattr(component_cls, \"run_async\", None)\n        if async_run is not None:\n            run_sockets = Sockets(instance, {}, InputSocket)\n            async_run_sockets = Sockets(instance, {}, InputSocket)","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/core/component/component.py#L236-L272","documentation":"When set_input_types()/set_input_type() is called in a component's constructor, Haystack later merges those sockets with the sockets derived from the run method signature. If a manually set socket targets the same parameter name as a run() parameter but with a different type/default, the merge raises this ComponentError, since the explicit spec would silently override the method's actual contract.","triggerScenarios":"Calling component.set_input_type('param', type=X) or set_input_types({...}) in __init__ where 'param' also exists as a parameter of run with a different annotated type (e.g. run(self, q: str) but set_input_type('q', list[int])), or with an incompatible default value.","commonSituations":"Declaring dynamic/Any-typed inputs for LLM components (set_input_types(prompt=str, **...)) but the run signature already annotates those params; copy-paste from an old component where the run signature changed; renaming a run parameter while keeping the old set_input_types call.","solutions":["Remove the set_input_types()/set_input_type() call for parameters already declared in the run signature — the run annotation is authoritative.","Align the type in set_input_type with the run parameter annotation exactly (InputSocket equality compares name, type, and default).","If a different input type is truly needed, change the run method's annotation to match.","For extra dynamic inputs, give them distinct names not present in the run signature."],"exampleFix":"// before\ndef __init__(self):\n    component.set_input_type(self, \"prompt\", List[int])\n@component.output_types(...)\ndef run(self, prompt: str): ...\n// after\n@component.output_types(...)\ndef run(self, prompt: List[int]): ...  # or drop the set_input_type call","handlingStrategy":"validation","validationCode":"import inspect\nrun_params = inspect.signature(MyComponent.run).parameters\nfor name in dynamic_input_names:\n    if name in run_params:\n        raise TypeError(f\"'{name}' is already a run() parameter; set_input_type cannot override it\")","typeGuard":null,"tryCatchPattern":"try:\n    comp = MyComponent()\nexcept ComponentError as e:\n    if \"cannot override the parameters\" in str(e):\n        raise RuntimeError(\"Remove the set_input_types() entry that clashes with the run() signature\") from e","preventionTips":["Only use set_input_types for inputs not present in run()'s signature","Keep run() annotations and set_input_types specs identical when both are used","Review set_input_types calls after renaming run parameters","Diff run signatures against constructor calls in component tests"],"tags":["haystack","component","input-types","sockets","componenterror"],"backgroundTag":"input-spec-mismatch","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}