{"record":{"id":"97020ca45fc9a54b","repo":"NousResearch/hermes-agent","slug":"a-time-is-required","errorCode":null,"errorMessage":"a time is required","messagePattern":"a time is required","errorType":"validation","errorClass":"BlueprintFillError","httpStatus":null,"severity":"warning","filePath":"cron/blueprint_catalog.py","lineNumber":703,"sourceCode":"    \"thursday\": \"4\", \"friday\": \"5\", \"saturday\": \"6\",\n}\n\n\ndef _resolve_schedule(blueprint: AutomationBlueprint, values: Dict[str, Any]) -> str:\n    \"\"\"Fill the schedule_template placeholders from resolved slot values.\"\"\"\n    sched = blueprint.schedule_template\n\n    # A free-text `schedule` slot passes through verbatim (full flexibility).\n    if \"schedule\" in values and values[\"schedule\"]:\n        return str(values[\"schedule\"])\n\n    repl: Dict[str, str] = {}\n\n    # time -> minute/hour\n    time_val = values.get(\"time\")\n    if \"{minute}\" in sched or \"{hour}\" in sched:\n        if not time_val:\n            raise BlueprintFillError(\"a time is required\")\n        m = _TIME_RE.match(str(time_val).strip())\n        if not m:\n            raise BlueprintFillError(f\"invalid time {time_val!r} — use HH:MM (24h)\")\n        repl[\"hour\"] = str(int(m.group(1)))\n        repl[\"minute\"] = str(int(m.group(2)))\n\n    # weekday set -> dow\n    if \"{dow}\" in sched:\n        if \"recurrence\" in values:\n            preset = str(values.get(\"recurrence\", \"everyday\")).lower()\n            if preset not in WEEKDAY_PRESETS:\n                raise BlueprintFillError(\n                    f\"unknown recurrence {preset!r} — one of {', '.join(WEEKDAY_PRESETS)}\"\n                )\n            repl[\"dow\"] = WEEKDAY_PRESETS[preset]\n        elif \"day\" in values:\n            day = str(values.get(\"day\", \"\")).lower()\n            if day not in _DAY_TO_DOW:","sourceCodeStart":685,"sourceCodeEnd":721,"githubUrl":"https://github.com/NousResearch/hermes-agent/blob/c896c09c42910c584c4c7d2325b58c14713ea42c/cron/blueprint_catalog.py#L685-L721","documentation":"BlueprintFillError from _resolve_schedule in the cron blueprint catalog. The blueprint's schedule_template contains {minute} and/or {hour} placeholders, the user did not supply a free-text `schedule` override, and no `time` slot value was given — so the HH:MM needed to build the cron fields is absent. The error is user-facing by design so a form (or the agent) knows what to ask for next.","triggerScenarios":"Filling a time-of-day blueprint (template like '0 {hour} * * {dow}') via fill_blueprint with values that omit `time`, e.g. {'day': 'monday'} only, or {'time': ''}.","commonSituations":"A chat-driven job creation where the user said 'every monday' but never stated a time; a form submission with the time field left blank; passing recurrence but forgetting the default time slot.","solutions":["Supply `time` in HH:MM 24h form, e.g. {'time': '09:30', 'day': 'monday'}","Or bypass templating entirely by passing a full free-text `schedule` value, which is returned verbatim"],"exampleFix":"# before\nfill_blueprint(bp, {\"day\": \"monday\"})\n# BlueprintFillError: a time is required\n\n# after\nfill_blueprint(bp, {\"day\": \"monday\", \"time\": \"09:00\"})","handlingStrategy":"validation","validationCode":"def has_time_or_schedule(values: dict, template: str) -> bool:\n    if values.get(\"schedule\"):\n        return True\n    if \"{minute}\" in template or \"{hour}\" in template:\n        return bool(values.get(\"time\"))\n    return True","typeGuard":null,"tryCatchPattern":"from cron.blueprint_catalog import BlueprintFillError\n\ntry:\n    spec = fill_blueprint(bp, values)\nexcept BlueprintFillError as e:\n    if str(e) == \"a time is required\":\n        values[\"time\"] = ask_user(\"At what time? (HH:MM, 24h)\")\n        spec = fill_blueprint(bp, values)\n    else:\n        raise","preventionTips":["When a template needs {hour}/{minute}, always collect `time` before submitting","Offer a free-text `schedule` escape hatch for users who know cron syntax","Treat BlueprintFillError as conversational feedback: re-ask for the named field"],"tags":["cron","blueprint","validation","scheduling"],"backgroundTag":null,"analyzedSha":"c896c09c42910c584c4c7d2325b58c14713ea42c","analyzedAt":"2026-08-14T17:18:01.089Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}