NousResearch/hermes-agent · warning · BlueprintFillError

{s.name}={raw!r} not allowed — one of {', '.join(map(str, s.

Error message

{s.name}={raw!r} not allowed — one of {', '.join(map(str, s.options))}

What it means

BlueprintFillError: a slot declared type='enum' with strict=True has a fixed options list, and the submitted value (as a string) is not among the stringified options. This is an exhaustive whitelist — close-but-not-exact values are refused, not fuzzy-matched.

Source

Thrown at cron/blueprint_catalog.py:776

    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)

    # Render the prompt with whatever slots it references.
    try:
        prompt = blueprint.prompt_template.format(**resolved)
    except KeyError as e:
        raise BlueprintFillError(f"blueprint prompt missing value for {e}") from e

    spec: Dict[str, Any] = {
        "prompt": prompt,
        "schedule": schedule,
        "name": blueprint.title,
        "deliver": resolved.get("deliver", blueprint.deliver_default),
    }

View on GitHub (pinned to c896c09c42)

Solutions

  1. Use one of the exact options printed in the error message
  2. If calling programmatically, offer s.options to the user/agent as the choice set and submit verbatim

Example fix

# before
fill_blueprint(bp, {"deliver": "email digest"})
# BlueprintFillError: deliver='email digest' not allowed — one of email, telegram, none

# after
fill_blueprint(bp, {"deliver": "email"})
Defensive patterns

Strategy: type-guard

Validate before calling

def enum_ok(slot, value) -> bool:
    if slot.type == "enum" and slot.strict and slot.options:
        return str(value) in {str(o) for o in slot.options}
    return True

Type guard

from cron.blueprint_catalog import Slot

def is_allowed_enum_value(s: Slot, value) -> bool:
    if s.type != "enum" or not s.strict or not s.options:
        return True
    return str(value) in {str(o) for o in s.options}

Try / catch

try:
    spec = fill_blueprint(bp, values)
except BlueprintFillError as e:
    if "not allowed" in str(e):
        # re-ask with the exact options listed in the message
        values[slot_name] = choose_from(options_from_message(str(e)))
        spec = fill_blueprint(bp, values)
    else:
        raise

Prevention

When it happens

Trigger: fill_blueprint with e.g. deliver='email digest' when the enum's options are ['email', 'telegram', 'none']; case/format variants that don't string-match exactly also fail.

Common situations: Users free-typing an option label instead of picking from a list; the agent paraphrasing an enum value; a blueprint update that renamed options while old callers still submit the previous label.

Related errors


AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14). Data as JSON: /api/errors/6801f350f7a4af0d. Report an issue: GitHub.