mastra-ai/mastra · error · Error
Invalid cron expression: expected a non-empty cron string (e
Error message
Invalid cron expression: expected a non-empty cron string (e.g. "0 * * * *"), but received ${cron === undefined ? 'undefined' : JSON.stringify(cron)}. What it means
validateCron throws this when the cron argument is not a non-empty string (undefined, null, empty, or whitespace-only). It is the first gate before parsing the pattern with Croner, so callers get a clear message instead of an opaque parser failure.
Source
Thrown at packages/core/src/workflows/scheduler/cron.ts:11
import { Cron } from 'croner';
/**
* Validate a cron expression. Throws if the pattern is invalid.
*
* @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) {View on GitHub (pinned to 75dd419e61)
Solutions
- Provide a valid non-empty cron string, e.g. '0 * * * *'.
- Check where the cron value is sourced (env var, config) and ensure it is set before calling.
- Add an upstream check that cron is a non-empty string before constructing a schedule.
- Validate config parsing so empty values are rejected at load time.
Example fix
// before
validateCron(config.schedule?.cron);
// after
if (!config.schedule?.cron) throw new Error('schedule.cron is required');
validateCron(config.schedule.cron, config.schedule.timezone); Defensive patterns
Strategy: validation
Validate before calling
function assertCronPresent(cron: unknown): asserts cron is string {
if (typeof cron !== 'string' || cron.trim() === '') throw new Error(`cron must be a non-empty string, got ${JSON.stringify(cron)}`);
} Type guard
function isNonEmptyString(v: unknown): v is string { return typeof v === 'string' && v.trim() !== ''; } Try / catch
try {
validateCron(cron, tz);
} catch (e) {
if ((e as Error).message.startsWith('Invalid cron expression: expected a non-empty')) {
cron = DEFAULT_CRON; // or surface a config error
} else throw e;
} Prevention
- Validate schedule config (cron present and non-empty) at load time
- Use schema validation (e.g. zod .min(1)) for the cron field
- Fail fast on missing env vars that feed cron values
- Give schedules a documented default cron
When it happens
Trigger: Calling validateCron(undefined), validateCron(''), or validateCron(' '); passing a schedule config where the cron field was never populated (e.g. missing env var or empty YAML value).
Common situations: Schedule defined via config file/env where the cron key is missing; an object spread that omits cron; a form/UI submitting an empty cron field.
Related errors
- Invalid cron expression "${cron}": ${reason}
- 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/2f660443eef59592.
Report an issue: GitHub.