NousResearch/hermes-agent · warning · BlueprintFillError
unknown slot{'s' if len(unknown) > 1 else ''}: {', '.join(un
Error message
unknown slot{'s' if len(unknown) > 1 else ''}: {', '.join(unknown)} — valid: {', '.join(s.name for s in blueprint.slots)} What it means
BlueprintFillError from fill_blueprint: the values dict contains keys that are not slot names defined on the blueprint. Unknown keys are rejected on purpose — the docstring calls out that a typo'd tiem=07:15 must not silently create a job at the default time. The message enumerates the valid slot names.
Source
Thrown at cron/blueprint_catalog.py:764
def fill_blueprint(
blueprint: AutomationBlueprint,
values: Dict[str, Any],
*,
origin: Optional[Dict[str, Any]] = None,
) -> Dict[str, Any]:
"""Validate ``values`` and return ``cron.jobs.create_job`` kwargs.
Missing required (non-optional) slots raise BlueprintFillError naming the
slot, so a form can show field errors and the agent knows what to ask.
Unknown slot names are rejected (a typo'd ``tiem=07:15`` must not silently
create a job with the default time). Enum values are checked against their
options. The result is passed straight to ``create_job`` — no second schema.
"""
known = {s.name for s in blueprint.slots}
unknown = sorted(set(values) - known)
if unknown:
raise BlueprintFillError(
f"unknown slot{'s' if len(unknown) > 1 else ''}: "
f"{', '.join(unknown)} — valid: {', '.join(s.name for s in blueprint.slots)}"
)
resolved: Dict[str, Any] = {}
for s in blueprint.slots:
raw = values.get(s.name, s.default)
if raw in (None, ""):
if s.optional:
continue
raise BlueprintFillError(f"missing required value: {s.name} ({s.label})")
if s.type == "enum" and s.strict and s.options and str(raw) not in {str(o) for o in s.options}:
raise BlueprintFillError(
f"{s.name}={raw!r} not allowed — one of {', '.join(map(str, s.options))}"
)
resolved[s.name] = raw
schedule = _resolve_schedule(blueprint, resolved)
View on GitHub (pinned to c896c09c42)
Solutions
- Read the valid names listed in the error and re-submit with only those keys
- Inspect blueprint.slots ([s.name for s in bp.slots]) before building the values dict
- For schedule overrides use the reserved 'schedule' key, not cron field names
Example fix
# before
fill_blueprint(bp, {"tiem": "07:15"})
# BlueprintFillError: unknown slot: tiem — valid: time, day, deliver
# after
fill_blueprint(bp, {"time": "07:15"}) Defensive patterns
Strategy: type-guard
Validate before calling
def only_known_slots(bp, values: dict) -> dict:
known = {s.name for s in bp.slots} | {"schedule"}
unknown = set(values) - known
if unknown:
raise KeyError(f"typo? {sorted(unknown)}; valid: {sorted(known)}")
return values Type guard
from cron.blueprint_catalog import Blueprint
def is_valid_slot_map(bp: Blueprint, values: dict) -> bool:
known = {s.name for s in bp.slots}
return set(values) <= known Try / catch
from cron.blueprint_catalog import BlueprintFillError
try:
spec = fill_blueprint(bp, values)
except BlueprintFillError as e:
if str(e).startswith("unknown slot"):
raise ValueError(f"Fix slot names: {e}") from e
raise Prevention
- Build the values dict from blueprint.slots metadata, not hand-typed keys
- Unit-test blueprint callers against the current slot names so renames surface early
- Never pass cron field names (hour/minute) — use the `time` slot or `schedule`
When it happens
Trigger: fill_blueprint(bp, {'tiem': '07:15', 'day': 'monday'}) — 'tiem' is not in {s.name for s in bp.slots}, so it raises before any other validation runs.
Common situations: Typos in slot names; passing schedule-construction keywords (like 'hour'/'minute') directly instead of the slot 'time'; stale caller code after a blueprint renamed its slots.
Related errors
- a time is required
- invalid time {time_val!r} — use HH:MM (24h)
- unknown recurrence {preset!r} — one of {', '.join(WEEKDAY_PR
- unknown day {day!r}
- invalid interval {iv!r} — minutes as a positive integer
AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14).
Data as JSON: /api/errors/4092cc653b9e0608.
Report an issue: GitHub.