nexu-io/open-design · error · Error
--schedule ${kind} time must be HH:MM (24h)
Error message
--schedule ${kind} time must be HH:MM (24h) What it means
Thrown by parseScheduleFlag in the `od automation` CLI when the HH:MM portion of a `--schedule daily:HH:MM` or `--schedule weekdays:HH:MM` flag fails the 24h regex `/^[0-2]\d:[0-5]\d$/`. The hour and minute tokens are zero-padded with padStart before the test, so the check is purely on numeric range, not on whether you supplied leading zeros. The `${kind}` interpolates to `daily` or `weekdays`.
Source
Thrown at apps/daemon/src/cli.ts:10513
}
const parts = raw.split(':');
const kind = parts[0];
if (kind === 'hourly') {
const minute = Number(parts[1]);
if (!Number.isInteger(minute) || minute < 0 || minute > 59) {
throw new Error('--schedule hourly requires :<minute>, 0-59');
}
return { kind: 'hourly', minute };
}
if (kind === 'daily' || kind === 'weekdays') {
if (parts.length < 3) {
throw new Error(`--schedule ${kind} requires :HH:MM[:TZ]`);
}
const hh = parts[1];
const mm = parts[2];
const time = `${hh.padStart(2, '0')}:${mm.padStart(2, '0')}`;
if (!/^[0-2]\d:[0-5]\d$/.test(time)) {
throw new Error(`--schedule ${kind} time must be HH:MM (24h)`);
}
const timezone = parts.slice(3).join(':') || 'UTC';
return { kind, time, timezone };
}
if (kind === 'weekly') {
if (parts.length < 4) {
throw new Error('--schedule weekly requires :DAY:HH:MM[:TZ] (DAY is 0-6 or sun/mon/...)');
}
const dayToken = String(parts[1]).toLowerCase();
let weekday;
if (/^[0-6]$/.test(dayToken)) {
weekday = Number(dayToken);
} else if (AUTOMATION_WEEKDAY_TOKENS[dayToken] !== undefined) {
weekday = AUTOMATION_WEEKDAY_TOKENS[dayToken];
} else {
throw new Error(`--schedule weekly day must be 0-6 or sun..sat (got "${parts[1]}")`);
}
const time = `${parts[2].padStart(2, '0')}:${parts[3].padStart(2, '0')}`;View on GitHub (pinned to 5be4028344)
Solutions
- Use a plain 24h HH:MM value, e.g. `--schedule daily:14:30` (leading zeros optional, the parser pads).
- Remove any AM/PM suffix; 14:30 is 2:30pm, 09:30 is 9:30am.
- If you need a timezone, append it as a trailing colon segment: `--schedule daily:14:30:America/New_York`.
- Double-check the hour is 00-23 and the minute is 00-59 before submitting.
Example fix
// before --schedule daily:2:30pm // after --schedule daily:14:30
Defensive patterns
Strategy: validation
Validate before calling
// Validate a daily/weekdays schedule time before invoking the CLI/parser.
function isValid24hTime(raw: string): boolean {
const parts = raw.split(':');
if (parts.length < 3) return false;
const time = `${parts[1].padStart(2, '0')}:${parts[2].padStart(2, '0')}`;
return /^[0-2]\d:[0-5]\d$/.test(time);
}
// usage: isValid24hTime('daily:14:30') === true Try / catch
try {
const schedule = parseScheduleFlag(raw);
} catch (err) {
if (err instanceof Error && /time must be HH:MM/.test(err.message)) {
// surface a user-facing 'enter a valid 24h time' message
}
throw err;
} Prevention
- Always pass time as 24h HH:MM with no AM/PM suffix.
- Pre-validate the flag string with the same regex the parser uses.
- When embedding `od` in scripts, build the flag from numeric fields you control, not free user text.
When it happens
Trigger: Running `od automation create --schedule daily:25:30` (hour out of range), `--schedule weekdays:09:60` (minute >59), `--schedule daily:abc:def` (non-numeric), or `--schedule daily:2:30pm` (the `pm` suffix becomes the minute token and fails).
Common situations: Typing the time in 12-hour format with an AM/PM suffix, using `24:00` for midnight, appending seconds `09:30:00` (which actually passes here because only parts[1]/parts[2] are tested and the rest become timezone), or copy-pasting a locale-formatted time like `9.30`.
Related errors
- --schedule weekly requires :DAY:HH:MM[:TZ] (DAY is 0-6 or su
- --schedule weekly day must be 0-6 or sun..sat (got "${parts[
- --schedule weekly time must be HH:MM (24h)
- --schedule kind must be hourly|daily|weekdays|weekly (got "$
- --schedule is required. Forms: hourly:<minute> | daily:HH:MM
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/04cec1d0b4568afc.
Report an issue: GitHub.