deepset-ai/haystack · error · TypeError

{type(self.chat_generator).__name__} does not accept tools p

Error message

{type(self.chat_generator).__name__} does not accept tools parameter in its run method. The Agent component requires a chat generator that supports tools when tools are provided.

What it means

While building telemetry for a running pipeline, haystack/_telemetry.py calls each component's _get_telemetry_data() and requires it to return a dict. This TypeError is raised when a component's _get_telemetry_data returns another type (list, string, None, custom object), since the data is spread into a per-component dict entry. It indicates a custom/broken component implementation, not bad user input.

Source

Thrown at haystack/components/agents/agent.py:756

            messages = messages + user_messages

        if self._system_chat_prompt_builder is not None:
            system_messages = _render_prompt_messages(
                prompt_builder=self._system_chat_prompt_builder,
                expected_role=ChatRole.SYSTEM,
                prompt_label="system_prompt",
                kwargs=kwargs,
            )
            messages = system_messages + messages

        if all(m.is_from(ChatRole.SYSTEM) for m in messages):
            logger.warning("All messages provided to the Agent component are system messages. This is not recommended.")

        selected_tools = self._select_tools(tools=tools)
        flat_tools = flatten_tools_or_toolsets(tools=selected_tools)
        # Validate tool support once for the run (covers both init-time and runtime tools)
        if flat_tools and not self._chat_generator_supports_tools:
            raise TypeError(
                f"{type(self.chat_generator).__name__} does not accept tools parameter in its run method. "
                "The Agent component requires a chat generator that supports tools when tools are provided."
            )

        state_kwargs: dict[str, Any] = {key: kwargs[key] for key in self.resolved_state_schema.keys() if key in kwargs}
        state = State(schema=self.resolved_state_schema, data=state_kwargs)
        state.set("messages", messages)
        state.set("step_count", 0)
        state.set("token_usage", {})
        state.set("context_tokens", 0)
        state.set("tool_call_counts", {tool.name: 0 for tool in flat_tools})
        state.set("exit_reason", None)
        state.set("continue_run", False)
        state.set("tools", flat_tools)
        state.set("hook_context", hook_context or {})

        streaming_callback = select_streaming_callback(  # type: ignore[call-overload]
            init_callback=self.streaming_callback, runtime_callback=streaming_callback, requires_async=requires_async

View on GitHub (pinned to e318778c9b)

Solutions

  1. Fix the component class named in the error so its _get_telemetry_data returns a dict[str, Any].
  2. If it's a Mock/test double, set it with _get_telemetry_data returning {} (e.g. Mock(_get_telemetry_data=lambda: {})).
  3. As a workaround, disable telemetry (HAYSTACK_TELEMETRY_ENABLED=False) or remove/replace the offending component from the pipeline.

Example fix

// before
class MyComponent:
    def _get_telemetry_data(self):
        return [self.init_parameters]
// after
class MyComponent:
    def _get_telemetry_data(self):
        return {"init_parameters": self.init_parameters}
Defensive patterns

Strategy: type-guard

Validate before calling

def telemetry_data_is_dict(component) -> bool:
    getter = getattr(component, "_get_telemetry_data", None)
    if getter is None:
        return True  # component is skipped by telemetry
    result = getter()
    return isinstance(result, dict)

Type guard

def is_valid_telemetry_data(data) -> bool:
    return isinstance(data, dict)

Try / catch

try:
    result = pipeline.run(...)
except TypeError as e:
    if "must be a dictionary" in str(e):
        logger.error("Component _get_telemetry_data must return a dict: %s", e)
        raise
    raise

Prevention

When it happens

Trigger: pipeline.run() / run_async_generator() walking a pipeline containing a component whose _get_telemetry_data is overridden to return a non-dict (or a Mock in tests); triggered inside pipeline_running() during telemetry emission when telemetry is enabled.

Common situations: Custom components overriding _get_telemetry_data incorrectly; test doubles/Mocks replacing components without dict-returning stubs (hence test names like test_pipeline_running_with_non_serializable_component); version mismatch where a component's telemetry hook signature changed.

Related errors


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