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 thatView on GitHub (pinned to e318778c9b)
Solutions
- Rewrite __init__ to declare explicit named parameters instead of *args, forwarding them explicitly.
- Collect extras as keyword-only via **kwargs instead of *args — only positional variadic args are rejected.
- Instantiate the component without positional arguments (pass everything by keyword) — the hook still inspects the signature, so fixing the signature is the real fix.
- 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
- Declare explicit named params in @component __init__
- Use **kwargs, never *args, when forwarding extra options
- Run unit tests that instantiate every component before pipeline use
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
- Output type specifications of 'run' and 'run_async' methods
- set_input_types()/set_input_type() cannot override the param
- Parameters of 'run' and 'run_async' methods must be the same
- Method 'run_async' of component '{cls.__name__}' must be a c
- Cannot set input types on a component that doesn't have a kw
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/c9b19e89f4672d53.
Report an issue: GitHub.