deepset-ai/haystack · error · ComponentError

Pre-init hooks do not support components with variadic posit

Error message

Pre-init hooks do not support components with variadic positional args in their init method

What it means

Haystack's pre-init hooks (wiring the __init__ positional args into kwargs before a component is fully registered) map positional args to __init__ parameters by position. If __init__ declares *args (VAR_POSITIONAL), the mapping is impossible, so a ComponentError is raised. The library requires component __init__ signatures to be enumerable as named parameters.

Source

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

    # note: Protocol member Component.run expected settable variable, got read-only attribute

    def run(self, *args: Any, **kwargs: Any) -> Mapping[str, Any]:  # noqa: D102
        ...


class ComponentMeta(type):
    @staticmethod
    def _positional_to_kwargs(cls_type: type, args: tuple[Any, ...]) -> dict[str, Any]:
        """
        Convert positional arguments to keyword arguments based on the signature of the `__init__` method.
        """
        init_signature = inspect.signature(cls_type.__init__)  # type:ignore[misc]
        init_params = {name: info for name, info in init_signature.parameters.items() if name != "self"}

        out = {}
        for arg, (name, info) in zip(args, init_params.items(), strict=False):
            if info.kind == inspect.Parameter.VAR_POSITIONAL:
                raise ComponentError(
                    "Pre-init hooks do not support components with variadic positional args in their init method"
                )

            assert info.kind in (inspect.Parameter.POSITIONAL_OR_KEYWORD, inspect.Parameter.POSITIONAL_ONLY)
            out[name] = arg
        return out

    @staticmethod
    def _parse_and_set_output_sockets(instance: Any) -> None:
        has_async_run = hasattr(instance, "run_async")

        # If `component.set_output_types()` was called in the component constructor,
        # `__haystack_output__` is already populated, no need to do anything.
        if not hasattr(instance, "__haystack_output__"):
            # If that's not the case, we need to populate `__haystack_output__`
            #
            # If either of the run methods were decorated, they'll have a field assigned that
            # stores the output specification. If both run methods were decorated, we ensure that

View on GitHub (pinned to e318778c9b)

Solutions

  1. Rewrite __init__ to declare explicit named parameters instead of *args, forwarding them explicitly.
  2. Collect extras as keyword-only via **kwargs instead of *args — only positional variadic args are rejected.
  3. Instantiate the component without positional arguments (pass everything by keyword) — the hook still inspects the signature, so fixing the signature is the real fix.
  4. If the class cannot be changed, wrap it in an adapter component with a named-parameter __init__.

Example fix

// before
class MyComponent:
    @component
    def __init__(self, *args):
        ...
// after
class MyComponent:
    @component
    def __init__(self, api_key: str, model: str):
        ...
Defensive patterns

Strategy: validation

Validate before calling

import inspect
params = inspect.signature(MyComponent.__init__).parameters
if any(p.kind == inspect.Parameter.VAR_POSITIONAL for p in params.values()):
    raise TypeError("@component __init__ must not declare *args")

Type guard

def has_named_init(cls: type) -> bool:
    return not any(
        p.kind == inspect.Parameter.VAR_POSITIONAL
        for p in inspect.signature(cls.__init__).parameters.values()
    )

Try / catch

try:
    comp = MyComponent("key", "model")
except ComponentError as e:
    if "variadic positional args" in str(e):
        comp = MyComponent(api_key="key", model="model")

Prevention

When it happens

Trigger: Instantiating a @component class whose __init__ contains *args positional variadic parameters, so ComponentMeta's pre-init hook (invoked on __init__ before the run method is set) cannot convert positional args to kwargs.

Common situations: Wrapping a third-party client class with variadic __init__ (e.g. def __init__(self, *args, **kwargs)) and decorating it with @component; forwarding args to an underlying SDK constructor.

Related errors


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