{"record":{"id":"30e654f70311df19","repo":"nexu-io/open-design","slug":"schedule-hourly-requires-minute-0-59","errorCode":null,"errorMessage":"--schedule hourly requires :<minute>, 0-59","messagePattern":"--schedule hourly requires :<minute>, 0-59","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/daemon/src/cli.ts","lineNumber":10501,"sourceCode":"// external agent (hermes-agent, openclaw, custom Slackbot, etc.) can run\n// the full lifecycle — list, create, fire, harvest, retire — without\n// rendering a page. Storage is /api/routines on the local daemon; the\n// \"routine\" name is the implementation detail, \"automation\" is the user-\n// facing surface.\n// ---------------------------------------------------------------------------\n\nfunction parseScheduleFlag(raw) {\n  if (!raw || typeof raw !== 'string') {\n    throw new Error(\n      '--schedule is required. Forms: hourly:<minute> | daily:HH:MM[:TZ] | weekdays:HH:MM[:TZ] | weekly:DAY:HH:MM[:TZ]',\n    );\n  }\n  const parts = raw.split(':');\n  const kind = parts[0];\n  if (kind === 'hourly') {\n    const minute = Number(parts[1]);\n    if (!Number.isInteger(minute) || minute < 0 || minute > 59) {\n      throw new Error('--schedule hourly requires :<minute>, 0-59');\n    }\n    return { kind: 'hourly', minute };\n  }\n  if (kind === 'daily' || kind === 'weekdays') {\n    if (parts.length < 3) {\n      throw new Error(`--schedule ${kind} requires :HH:MM[:TZ]`);\n    }\n    const hh = parts[1];\n    const mm = parts[2];\n    const time = `${hh.padStart(2, '0')}:${mm.padStart(2, '0')}`;\n    if (!/^[0-2]\\d:[0-5]\\d$/.test(time)) {\n      throw new Error(`--schedule ${kind} time must be HH:MM (24h)`);\n    }\n    const timezone = parts.slice(3).join(':') || 'UTC';\n    return { kind, time, timezone };\n  }\n  if (kind === 'weekly') {\n    if (parts.length < 4) {","sourceCodeStart":10483,"sourceCodeEnd":10519,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/cli.ts#L10483-L10519","documentation":"Thrown by parseScheduleFlag for the `hourly` kind when the minute part is missing, non-numeric, or outside 0-59. The check is `Number.isInteger(minute) && minute >= 0 && minute <= 59`. The schedule format is `hourly:<minute>`.","triggerScenarios":"`--schedule hourly`, `--schedule hourly:`, `--schedule hourly:60`, `--schedule hourly:abc`, or `--schedule hourly:-5`.","commonSituations":"Forgetting the minute component; using 24-hour-style '60' for the top of the hour; passing a fractional minute; copy-paste error from a daily schedule that left HH:MM in place.","solutions":["Use `--schedule hourly:<minute>` with an integer 0-59, e.g. `hourly:30` to run on the half-hour.","If you meant a specific time of day, switch to `daily:HH:MM[:TZ]` instead.","Double-check the value is an integer — leading zeros are fine, decimals are not.","Use --help to confirm the hourly grammar."],"exampleFix":"# before\nod automation create --name h --prompt-file p.txt --schedule hourly:60\n# after\nod automation create --name h --prompt-file p.txt --schedule hourly:30","handlingStrategy":"validation","validationCode":"function parseHourlyMinute(raw) {\n  const m = /^hourly:(\\d{1,2})$/.exec(raw);\n  const minute = m ? Number(m[1]) : NaN;\n  if (!Number.isInteger(minute) || minute < 0 || minute > 59) {\n    throw new Error('--schedule hourly requires :<minute>, 0-59');\n  }\n  return minute;\n}","typeGuard":"const isHourlyMinute = (v: unknown): boolean => {\n  if (typeof v !== 'string') return false;\n  const m = /^hourly:(\\d{1,2})$/.exec(v);\n  const n = m ? Number(m[1]) : NaN;\n  return Number.isInteger(n) && n >= 0 && n <= 59;\n};","tryCatchPattern":null,"preventionTips":["Always include a 0-59 minute: `hourly:30`.","For a specific time of day, use `daily:HH:MM[:TZ]` instead.","Reject fractional minutes and '60'."],"tags":["cli","automation","schedule","argument-parsing","validation"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}