{"record":{"id":"2f660443eef59592","repo":"mastra-ai/mastra","slug":"invalid-cron-expression-expected-a-non-empty-cron","errorCode":null,"errorMessage":"Invalid cron expression: expected a non-empty cron string (e.g. \"0 * * * *\"), but received ${cron === undefined ? 'undefined' : JSON.stringify(cron)}.","messagePattern":"Invalid cron expression: expected a non-empty cron string \\(e\\.g\\. \"0 \\* \\* \\* \\*\"\\), but received (.+?)\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/workflows/scheduler/cron.ts","lineNumber":11,"sourceCode":"import { Cron } from 'croner';\n\n/**\n * Validate a cron expression. Throws if the pattern is invalid.\n *\n * @param cron - Cron expression (5-, 6-, or 7-part).\n * @param timezone - Optional IANA timezone (e.g. 'America/New_York').\n */\nexport function validateCron(cron: string, timezone?: string): void {\n  if (typeof cron !== 'string' || cron.trim() === '') {\n    throw new Error(\n      `Invalid cron expression: expected a non-empty cron string (e.g. \"0 * * * *\"), but received ${cron === undefined ? 'undefined' : JSON.stringify(cron)}.`,\n    );\n  }\n  // Croner throws synchronously on an invalid pattern when the job is\n  // constructed. Validate the pattern on its own first so timezone problems\n  // (which croner only surfaces lazily) are not mislabeled as cron errors.\n  let job: Cron;\n  try {\n    job = new Cron(cron);\n  } catch (error) {\n    const reason = error instanceof Error ? error.message : String(error);\n    throw new Error(`Invalid cron expression \"${cron}\": ${reason}`);\n  }\n  // The timezone is only exercised when a fire time is computed.\n  if (timezone !== undefined) {\n    try {\n      new Cron(cron, { timezone }).nextRun();\n    } catch (error) {","sourceCodeStart":1,"sourceCodeEnd":29,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/workflows/scheduler/cron.ts#L1-L29","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nvalidateCron(config.schedule?.cron);\n// after\nif (!config.schedule?.cron) throw new Error('schedule.cron is required');\nvalidateCron(config.schedule.cron, config.schedule.timezone);","handlingStrategy":"validation","validationCode":"function assertCronPresent(cron: unknown): asserts cron is string {\n  if (typeof cron !== 'string' || cron.trim() === '') throw new Error(`cron must be a non-empty string, got ${JSON.stringify(cron)}`);\n}","typeGuard":"function isNonEmptyString(v: unknown): v is string { return typeof v === 'string' && v.trim() !== ''; }","tryCatchPattern":"try {\n  validateCron(cron, tz);\n} catch (e) {\n  if ((e as Error).message.startsWith('Invalid cron expression: expected a non-empty')) {\n    cron = DEFAULT_CRON; // or surface a config error\n  } else throw e;\n}","preventionTips":["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"],"tags":["workflows","scheduler","cron","validation"],"backgroundTag":"invalid-cron-expression","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}