deepset-ai/haystack · error · TypeError
{type(chat_generator).__name__} does not accept tools parame
Error message
{type(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
warm_up builds a dict keyed by skill name; skill names must be unique across the store. This ValueError is raised when two skill files resolve to the same name — either both declare the same 'name' in frontmatter, or one's frontmatter name collides with another skill's directory name (used as fallback when 'name' is absent).
Source
Thrown at haystack/components/agents/agent.py:464
Agent running by setting the `continue_run` control flag (`state.set("continue_run", True)`), usually
alongside a message telling the model what to do next. "on_exit" hooks run when the Agent stops on an
exit condition, but not when it stops because `max_agent_steps` is reached.
- "after_run": Runs once per run, after the step loop has ended and before the Agent builds its return
value — regardless of whether the run stopped on an exit condition or because `max_agent_steps` was
reached (unlike "on_exit"). Mutations to the state (e.g. appending a final message) are reflected in
the returned `messages` / `last_message` and `state_schema` outputs. Setting `continue_run` here has
no effect.
:raises TypeError: If the chat_generator does not support tools parameter in its run method.
:raises ValueError: If any `user_prompt` variable overlaps with the `state_schema` or `run` method parameters,
if a hook is registered under an unknown hook point, or if a hook is registered under a hook point it does
not support (via its `allowed_hook_points`).
"""
# --- Validation ---
self._chat_generator_supports_tools: bool = "tools" in inspect.signature(chat_generator.run).parameters
# We use an explicit None check for tools b/c testing for truthiness calls __len__, which for SearchableToolset
# would iterate and prematurely warm it up at init.
if tools is not None and not self._chat_generator_supports_tools:
raise TypeError(
f"{type(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."
)
if exit_conditions is None:
exit_conditions = ["text"]
if state_schema is not None:
reserved_keys = _RUN_METADATA_STATE_KEYS.keys() | _INTERNAL_STATE_KEYS.keys()
reserved_used = sorted(set(state_schema) & reserved_keys)
if reserved_used:
raise ValueError(
f"state_schema keys {reserved_used} are reserved for Agent internal state and "
f"cannot be redefined. Reserved keys: {sorted(reserved_keys)}."
)
_validate_schema(state_schema)
_validate_prompt_message_blocks(user_prompt, system_prompt)
if tool_concurrency_limit < 1:View on GitHub (pinned to e318778c9b)
Solutions
- Rename the 'name' field in one of the colliding skills' frontmatter so each name is unique.
- If the collision comes from directory-name fallback, either set an explicit unique 'name' or rename the skill directory.
- Remove duplicate/copied skill directories or symlinks from skills_dir.
Example fix
// before (skills/backup/SKILL.md and skills/backup-v2/SKILL.md) name: backup // after (backup-v2/SKILL.md) name: backup-v2
Defensive patterns
Strategy: validation
Validate before calling
import yaml
from pathlib import Path
from collections import Counter
def find_duplicate_skill_names(skills_dir: Path) -> list[str]:
names = []
for md in skills_dir.glob("**/*.md"):
lines = md.read_text(encoding="utf-8").splitlines()
if lines and lines[0].strip() == "---":
closing = lines.index("---", 1)
fm = yaml.safe_load("\n".join(lines[1:closing])) or {}
names.append(fm.get("name", md.parent.name))
return [n for n, c in Counter(names).items() if c > 1] Try / catch
try:
store.list_skills()
except ValueError as e:
if "Duplicate skill name" in str(e):
logger.error("Rename one of the colliding skills: %s", e)
raise Prevention
- When copying a skill to iterate, immediately change its frontmatter 'name'
- Keep skill directory names and frontmatter names identical to avoid fallback collisions
- Run a duplicate-name check over skills_dir in CI
When it happens
Trigger: Two .md skill files in skills_dir declaring 'name: my-skill'; or skill dirs 'foo/' and 'bar/' where bar/SKILL.md declares 'name: foo'. Detected during warm_up via list_skills/load_skill.
Common situations: Copying a skill directory to iterate on it without changing the frontmatter 'name'; a nested directory plus a top-level skill sharing the frontmatter name; symlinks or duplicated skills checked into the repo twice.
Related errors
- Hook registered for hook point '{hook_point}' must have a ca
- Hook of type '{type(h).__name__}' is registered under hook p
- Invalid hook point '{hook_point}'. Valid hook points are: {'
- Hook registered for hook point '{hook_point}' is callable bu
- state_schema keys {reserved_used} are reserved for Agent int
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/77deb03ec42bb735.
Report an issue: GitHub.