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_asyncView on GitHub (pinned to e318778c9b)
Solutions
- Fix the component class named in the error so its _get_telemetry_data returns a dict[str, Any].
- If it's a Mock/test double, set it with _get_telemetry_data returning {} (e.g. Mock(_get_telemetry_data=lambda: {})).
- 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
- Always return a dict from custom components' _get_telemetry_data overrides
- In tests, configure Mocks with _get_telemetry_data returning {} (e.g. Mock(_get_telemetry_data=Mock(return_value={})))
- Add a unit test asserting each component's telemetry payload is a dict
- Keep haystack and component libraries on compatible versions so telemetry hook contracts match
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
- PipelineRuntimeError.from_invalid_output(component_name, ins
- Hook registered for hook point '{hook_point}' is callable bu
- The {self.__class__.__name__} expects a list containing only
- Unsupported source type {type(source)}
- meta must be either None, a dictionary or a list of dictiona
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/2c3ec678597a68ce.
Report an issue: GitHub.