deepset-ai/haystack · error · ComponentError

set_input_types()/set_input_type() cannot override the param

Error message

set_input_types()/set_input_type() cannot override the parameters of the 'run' method

What it means

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.

Source

Thrown at haystack/core/component/component.py:254

            run_signature = inspect.signature(method)
            # Resolves the annotations of components using postponed evaluation of annotations, where they are stored
            # as strings.
            param_types = _resolve_parameter_types(method)

            for param_name, param_info in run_signature.parameters.items():
                if param_name == "self" or param_info.kind in (Parameter.VAR_POSITIONAL, Parameter.VAR_KEYWORD):
                    continue

                socket_kwargs = {"name": param_name, "type": param_types[param_name]}
                if param_info.default != Parameter.empty:
                    socket_kwargs["default_value"] = param_info.default

                new_socket = InputSocket(**socket_kwargs)

                # Also ensure that new sockets don't override existing ones.
                existing_socket = sockets.get(param_name)
                if existing_socket is not None and existing_socket != new_socket:
                    raise ComponentError(
                        "set_input_types()/set_input_type() cannot override the parameters of the 'run' method"
                    )

                sockets[param_name] = new_socket

            return run_signature

        # Create the sockets if set_input_types() wasn't called in the constructor.
        if not hasattr(instance, "__haystack_input__"):
            instance.__haystack_input__ = Sockets(instance, {}, InputSocket)

        inner(getattr(component_cls, "run"), instance.__haystack_input__)  # noqa: B009

        # Ensure that the sockets are the same for the async method, if it exists.
        async_run = getattr(component_cls, "run_async", None)
        if async_run is not None:
            run_sockets = Sockets(instance, {}, InputSocket)
            async_run_sockets = Sockets(instance, {}, InputSocket)

View on GitHub (pinned to e318778c9b)

Solutions

  1. Remove the set_input_types()/set_input_type() call for parameters already declared in the run signature — the run annotation is authoritative.
  2. Align the type in set_input_type with the run parameter annotation exactly (InputSocket equality compares name, type, and default).
  3. If a different input type is truly needed, change the run method's annotation to match.
  4. For extra dynamic inputs, give them distinct names not present in the run signature.

Example fix

// before
def __init__(self):
    component.set_input_type(self, "prompt", List[int])
@component.output_types(...)
def run(self, prompt: str): ...
// after
@component.output_types(...)
def run(self, prompt: List[int]): ...  # or drop the set_input_type call
Defensive patterns

Strategy: validation

Validate before calling

import inspect
run_params = inspect.signature(MyComponent.run).parameters
for name in dynamic_input_names:
    if name in run_params:
        raise TypeError(f"'{name}' is already a run() parameter; set_input_type cannot override it")

Try / catch

try:
    comp = MyComponent()
except ComponentError as e:
    if "cannot override the parameters" in str(e):
        raise RuntimeError("Remove the set_input_types() entry that clashes with the run() signature") from e

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30). Data as JSON: /api/errors/cfca59a5ac897ff2. Report an issue: GitHub.