fix(kanban): unknown skill warns instead of crashing the worker

A Kanban task referencing a non-existent skill (e.g. a typo'd name)
crashed the worker on startup via ValueError, which the dispatcher
retried until the task auto-blocked. Both cli.py and tui_gateway/server.py
now skip the unknown skill(s), log a warning, and continue with whatever
loaded — but still hard-fail when EVERY requested skill is missing, so a
fully-misconfigured worker fails loudly instead of running blind.

Closes #27136

Co-authored-by: Jimmy Johansson <jimmyjohansson84@users.noreply.github.com>
This commit is contained in:
Jimmy Johansson 2026-06-30 03:30:13 -07:00 committed by Teknium
parent c701c6dad7
commit 018009bc38
2 changed files with 30 additions and 3 deletions

16
cli.py
View file

@ -15359,7 +15359,21 @@ def main(
)
if missing_skills:
missing_display = ", ".join(missing_skills)
raise ValueError(f"Unknown skill(s): {missing_display}")
# If at least one skill loaded, degrade gracefully: skip the
# unknown ones and continue. A typo'd skill name should not crash
# the worker (which auto-blocks the Kanban task after retries).
# Only when EVERY requested skill is missing do we hard-fail, so a
# fully-misconfigured worker fails loudly instead of running blind.
if loaded_skills:
logger.warning(
"Unknown skill(s) requested, skipping: %s. "
"Continuing with: %s. "
"List available skills with `hermes skills list`.",
missing_display,
", ".join(loaded_skills),
)
else:
raise ValueError(f"Unknown skill(s): {missing_display}")
if skills_prompt:
cli.system_prompt = "\n\n".join(
part for part in (cli.system_prompt, skills_prompt) if part

View file

@ -4212,12 +4212,25 @@ def _make_agent(
if startup_skills:
from agent.skill_commands import build_preloaded_skills_prompt
skills_prompt, _loaded_skills, missing_skills = build_preloaded_skills_prompt(
skills_prompt, loaded_skills, missing_skills = build_preloaded_skills_prompt(
startup_skills,
task_id=session_id or key,
)
if missing_skills:
raise ValueError(f"Unknown skill(s): {', '.join(missing_skills)}")
missing_display = ", ".join(missing_skills)
# Degrade gracefully when some skills loaded; only hard-fail when
# every requested skill is missing. Mirrors cli.py — a typo'd skill
# name should not crash the worker and auto-block the Kanban task.
if loaded_skills:
logger.warning(
"Unknown skill(s) requested, skipping: %s. "
"Continuing with: %s. "
"List available skills with `hermes skills list`.",
missing_display,
", ".join(loaded_skills),
)
else:
raise ValueError(f"Unknown skill(s): {missing_display}")
if skills_prompt:
system_prompt = "\n\n".join(
part for part in (system_prompt, skills_prompt) if part