mastra-ai/mastra · error · Error
Invalid cron expression "${cron}": ${reason}
Error message
Invalid cron expression "${cron}": ${reason} What it means
validateCron throws this when the cron string is non-empty but Croner rejects the pattern itself (e.g. wrong field count, out-of-range values). The original Croner message is included as the reason so the specific syntax problem is visible.
Source
Thrown at packages/core/src/workflows/scheduler/cron.ts:23
*
* @param cron - Cron expression (5-, 6-, or 7-part).
* @param timezone - Optional IANA timezone (e.g. 'America/New_York').
*/
export function validateCron(cron: string, timezone?: string): void {
if (typeof cron !== 'string' || cron.trim() === '') {
throw new Error(
`Invalid cron expression: expected a non-empty cron string (e.g. "0 * * * *"), but received ${cron === undefined ? 'undefined' : JSON.stringify(cron)}.`,
);
}
// Croner throws synchronously on an invalid pattern when the job is
// constructed. Validate the pattern on its own first so timezone problems
// (which croner only surfaces lazily) are not mislabeled as cron errors.
let job: Cron;
try {
job = new Cron(cron);
} catch (error) {
const reason = error instanceof Error ? error.message : String(error);
throw new Error(`Invalid cron expression "${cron}": ${reason}`);
}
// The timezone is only exercised when a fire time is computed.
if (timezone !== undefined) {
try {
new Cron(cron, { timezone }).nextRun();
} catch (error) {
const reason = error instanceof Error ? error.message : String(error);
throw new Error(`Invalid timezone "${timezone}": ${reason}`);
}
} else {
job.nextRun();
}
}
/**
* Compute the next fire time (ms since epoch) for a cron expression.
*
* @param cron - Cron expression.View on GitHub (pinned to 75dd419e61)
Solutions
- Read the embedded reason from Croner and fix the offending field(s) in the expression.
- Use a standard 5-part expression (minute hour day month weekday) or a supported 6/7-part form.
- Test the pattern with an online cron parser or by running computeNextFireAt to confirm it yields a time.
- Keep cron strings in validated config/schema rather than free-form strings.
Example fix
// before
validateCron('0 25 * * *'); // hour 25 is invalid
// after
validateCron('0 5 * * *'); Defensive patterns
Strategy: validation
Validate before calling
function preCheckCron(cron: string) {
const parts = cron.trim().split(/\s+/);
if (parts.length < 5 || parts.length > 7) throw new Error(`cron must have 5-7 fields, got ${parts.length}: "${cron}"`);
} Try / catch
try {
validateCron(cron);
} catch (e) {
const msg = (e as Error).message;
if (msg.startsWith('Invalid cron expression "')) {
console.error(`Bad cron pattern: ${cron}. ${msg}`);
} else throw e;
} Prevention
- Test cron strings with a parser or computeNextFireAt before deploying
- Keep cron expressions in reviewed config, not inline literals
- Document the supported 5/6/7-field format for your team
- Add cron pattern tests to CI
When it happens
Trigger: Calling validateCron('99 99 * * *') (out-of-range fields), validateCron('* * *') (too few parts), or any malformed pattern such as '*/foo * * * *' — any input where `new Cron(cron)` throws synchronously.
Common situations: Typos in cron fields; using seconds-level 6/7-part syntax incorrectly; copying cron from another system with unsupported syntax; hand-editing schedules in production.
Related errors
- Invalid cron expression: expected a non-empty cron string (e
- Invalid timezone "${timezone}": ${reason}
- Cron expression "${cron}" has no future occurrence after ${r
- GitHub issue reconcile interval must be a positive number.
- SCHEDULES_INVALID_CRON
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/e06a791232e4f11c.
Report an issue: GitHub.