mastra-ai/mastra · error
Invalid timezone "${timezone}": ${reason}
Error message
Invalid timezone "${timezone}": ${reason} What it means
validateCron throws this when the optional timezone argument is not a valid IANA timezone. Croner only surfaces timezone problems lazily when a fire time is computed, so validateCron explicitly computes nextRun with the timezone to catch and label it here.
Source
Thrown at packages/core/src/workflows/scheduler/cron.ts:31
);
}
// 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.
* @param options - Optional timezone and reference time (`after`, ms since epoch).
* The next fire time is the first cron occurrence strictly after `after`.
* Defaults to `Date.now()`.
* @returns The next fire time in ms since epoch.
* @throws If the cron expression is invalid or has no future occurrence.
*/
export function computeNextFireAt(cron: string, options?: { timezone?: string; after?: number }): number {
const job = new Cron(cron, { timezone: options?.timezone });View on GitHub (pinned to 75dd419e61)
Solutions
- Use a valid IANA timezone string like 'America/New_York' or 'Europe/Berlin'.
- Check the embedded reason — the original Croner error names the bad timezone.
- Validate against Intl.supportedValuesOf('timeZone') before calling.
- Omit the timezone parameter if UTC is acceptable.
Example fix
// before
validateCron('0 * * * *', 'EST');
// after
validateCron('0 * * * *', 'America/New_York'); Defensive patterns
Strategy: validation
Validate before calling
function isIANATimezone(tz: string): boolean {
try { new Intl.DateTimeFormat('en-US', { timeZone: tz }); return true; } catch { return false; }
} Type guard
function isValidTimezone(tz: unknown): tz is string {
return typeof tz === 'string' && (() => { try { new Intl.DateTimeFormat('en-US', { timeZone: tz }); return true; } catch { return false; } })();
} Try / catch
try {
validateCron(cron, timezone);
} catch (e) {
if ((e as Error).message.startsWith('Invalid timezone')) {
timezone = 'UTC';
} else throw e;
} Prevention
- Always use full IANA names (Continent/City), never abbreviations like EST
- Validate timezone against Intl.supportedValuesOf('timeZone') at config load
- Default to 'UTC' when timezone is optional and unverified
- Avoid OS-specific zone names that differ from the IANA database
When it happens
Trigger: Calling validateCron('0 * * * *', 'America/New_York ') with a typo ('America/News_York'), a non-IANA name ('EST'), or a locale-style offset ('UTC+2'); computing nextRun with that timezone throws and is rethrown as this error.
Common situations: Hardcoded abbreviations instead of IANA names; mis-typed timezone from user config; timezone names taken from OS-specific databases that differ from the IANA set.
Related errors
- Invalid cron expression: expected a non-empty cron string (e
- Invalid cron expression "${cron}": ${reason}
- Cron expression "${cron}" has no future occurrence after ${r
- Unsupported schedule target type: ${(schedule.target as { ty
- @mastra/livekit: no workflow specified. Set `workflow` on cr
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/716143895c717fe8.
Report an issue: GitHub.