deepset-ai/haystack · error · ComponentError

Cannot set input types on a component that doesn't have a kw

Error message

Cannot set input types on a component that doesn't have a kwargs parameter in the 'run' method

What it means

component.set_input_type() can only dynamically declare an input socket on components whose run method has a **kwargs parameter, because the socket has no corresponding named parameter to attach to otherwise. Calling it on such a component raises ComponentError.

Source

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

    def set_input_type(
        self,
        instance: Component,
        name: str,
        type: Any,  # noqa: A002
        default: Any = _empty,
    ) -> None:
        """
        Add a single input socket to the component instance.

        Replaces any existing input socket with the same name.

        :param instance: Component instance where the input type will be added.
        :param name: name of the input socket.
        :param type: type of the input socket.
        :param default: default value of the input socket, defaults to _empty
        """
        if not _component_run_has_kwargs(instance.__class__):
            raise ComponentError(
                "Cannot set input types on a component that doesn't have a kwargs parameter in the 'run' method"
            )

        if not hasattr(instance, "__haystack_input__"):
            instance.__haystack_input__ = Sockets(instance, {}, InputSocket)  # type: ignore
        instance.__haystack_input__[name] = InputSocket(name=name, type=type, default_value=default)  # type: ignore

    def set_input_types(self, instance: Any, **types: type[Any]) -> None:
        """
        Method that specifies the input types when 'kwargs' is passed to the run method.

        Use as:

        ```python
        @component
        class MyComponent:

            def __init__(self, value: int) -> None:

View on GitHub (pinned to e318778c9b)

Solutions

  1. Add `**kwargs` to the run method signature (and to run_async to keep them in sync), then call set_input_type
  2. Declare the input statically in the run signature instead of using set_input_type
  3. Use the @component.input_types decorator on run to declare inputs declaratively

Example fix

# before
class C:
    def run(self, x: int):
        return {"y": x}
set_input_type(C(), "extra", str)  # raises

# after
class C:
    def run(self, x: int, **kwargs):
        return {"y": x}

comp = C()
set_input_type(comp, "extra", str, default=None)
Defensive patterns

Strategy: validation

Validate before calling

from haystack.core.component.component import _component_run_has_kwargs
if not _component_run_has_keywords(type(comp)) if False else True:
    pass
def can_set_input_type(comp_cls) -> bool:
    sig = inspect.signature(comp_cls.run)
    return any(p.kind == inspect.Parameter.VAR_KEYWORD for p in sig.parameters.values())

Type guard

def run_accepts_kwargs(cls) -> bool:
    import inspect
    return any(
        p.kind == inspect.Parameter.VAR_KEYWORD
        for p in inspect.signature(cls.run).parameters.values()
    )

Try / catch

try:
    set_input_type(comp, "extra", str)
except ComponentError as e:
    logging.error("Add **kwargs to run() before calling set_input_type")
    raise

Prevention

When it happens

Trigger: Calling set_input_type(instance, name, type) (or with a default) on a component whose run signature is fully explicit (no **kwargs).

Common situations: Trying to add an extra optional input (like a retry_count or metadata) to a component with a fixed run signature; following docs examples for kwargs-based components while your component uses named params.

Related errors


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