deepset-ai/haystack · error · ValueError
state_schema keys {reserved_used} are reserved for Agent int
Error message
state_schema keys {reserved_used} are reserved for Agent internal state and cannot be redefined. Reserved keys: {sorted(reserved_keys)}. What it means
_skill_dir looks up the requested skill name in the warmed catalog and, on KeyError, raises a new KeyError listing the available skill names (or 'none'). This replaces the bare KeyError so callers can see which skills exist. It surfaces from load_skill, _list_skill_files, and read_skill_file.
Source
Thrown at haystack/components/agents/agent.py:476
"""
# --- 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:
raise ValueError("tool_concurrency_limit must be greater than or equal to 1.")
hooks = hooks or {}
_validate_hooks(hooks)
# --- Attributes ---
self.chat_generator = chat_generator
# 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.
self.tools = tools if tools is not None else []
self.system_prompt = system_prompt
self.user_prompt = user_promptView on GitHub (pinned to e318778c9b)
Solutions
- Use one of the names listed in the error's 'Available skills' list.
- Call store.list_skills() to get current names and fix the caller's lookup.
- If the skill should exist, check the frontmatter 'name' (or directory name) in skills_dir and that the store was constructed against the right directory.
Example fix
// before
skill = store.load_skill("code-review")
// after
available = store.list_skills()
skill = store.load_skill(available[0].name if available else "code-review") Defensive patterns
Strategy: try-catch
Validate before calling
def resolve_skill(store, wanted: str):
available = {s.name for s in store.list_skills()}
if wanted in available:
return wanted
lowered = {n.lower(): n for n in available}
return lowered.get(wanted.lower()) Try / catch
try:
skill = store.load_skill(name)
except KeyError as e:
logger.warning("Skill %r not found; available: %s", name, e)
skill = None # or retry with a corrected name Prevention
- Call list_skills() and pick names from it instead of hardcoding strings
- Match skill names case-sensitively and exactly as declared in frontmatter
- Refresh/reconstruct the store after changing skills_dir contents
- When an LLM picks skill names, constrain it to the list_skills() output
When it happens
Trigger: Calling store.load_skill('typo-name'), read_skill_file('typo-name', ...), or an agent requesting a skill name that isn't in skills_dir; also when warm_up failed earlier and the catalog is empty (though that usually raises error 402/403/404 first).
Common situations: Typos or case mismatch ('My-Skill' vs 'my-skill'); stale skill name after a rename; LLM agent hallucinating a skill name; skills_dir content changed but the store instance cached an old catalog.
Related errors
- Invalid hook point '{hook_point}'. Valid hook points are: {'
- Hook registered for hook point '{hook_point}' is callable bu
- Hook registered for hook point '{hook_point}' must have a ca
- Hook of type '{type(h).__name__}' is registered under hook p
- {type(chat_generator).__name__} does not accept tools parame
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/26a064ef9077f85c.
Report an issue: GitHub.