different-ai/openwork · error
Invalid IANA timezone: ${timezone}
Error message
Invalid IANA timezone: ${timezone} What it means
assertAutomationTimezone validates that a string is an IANA timezone the platform can format with (via Intl.DateTimeFormat). It constructs a formatter and formats epoch 0; any failure (unknown zone, bad identifier) raises a RangeError naming the offending timezone. Automation schedules need a real zone to compute occurrences.
Source
Thrown at packages/automations/src/schedule.ts:116
}
return shifted === null ? null : { timestamp: shifted, shifted: true }
}
function isScheduledDay(
schedule: AutomationSchedule,
weekday: number,
): boolean {
return (
schedule.kind === "daily" ||
(schedule.kind === "weekly" && schedule.daysOfWeek.includes(weekday))
)
}
export function assertAutomationTimezone(timezone: string): void {
try {
formatter(timezone).format(new Date(0))
} catch {
throw new RangeError(`Invalid IANA timezone: ${timezone}`)
}
}
export interface AutomationOccurrenceSearchOptions {
after: number
count?: number
}
export function automationOccurrences(
input: AutomationSchedule,
options: AutomationOccurrenceSearchOptions,
): { occurrences: number[]; warnings: string[] } {
const schedule = automationScheduleSchema.parse(input)
assertAutomationTimezone(schedule.timezone)
const count = Math.max(0, Math.min(options.count ?? 5, 5))
if (count === 0) {
return { occurrences: [], warnings: [] }
}View on GitHub (pinned to 2b7df46e8a)
Solutions
- Use canonical IANA zone identifiers (e.g. 'America/New_York'), not offsets or abbreviations
- Validate user input against Intl.supportedValuesOf('timeZone') before persisting
- Fix the runtime environment: upgrade Node/build with full-icu so all IANA zones resolve
- Fall back to 'UTC' (or ask the user to re-pick) when the configured zone is invalid
Example fix
// before
assertAutomationTimezone(config.tz) // "UTC+2"
// after
const tz = Intl.supportedValuesOf("timeZone").includes(config.tz) ? config.tz : "UTC"
assertAutomationTimezone(tz) Defensive patterns
Strategy: validation
Validate before calling
function isValidTimezone(tz: string): boolean {
try {
new Intl.DateTimeFormat("en-US", { timeZone: tz }).format(new Date(0))
return true
} catch {
return false
}
}
// call before: if (!isValidTimezone(config.tz)) config.tz = "UTC" Type guard
const isIanaTimezone = (tz: string): boolean => {
try { new Intl.DateTimeFormat("en-US", { timeZone: tz }).format(0); return true } catch { return false }
} Try / catch
try {
assertAutomationTimezone(tz)
} catch (e) {
if (e instanceof RangeError && e.message.startsWith("Invalid IANA timezone")) {
logger.warn(`${e.message}; falling back to UTC`)
tz = "UTC"
} else throw e
} Prevention
- Constrain timezone selection to a dropdown sourced from Intl.supportedValuesOf('timeZone')
- Store canonical IANA identifiers ('Europe/Paris'), never offsets like 'UTC+2'
- Run Node with full ICU data in minimal/container environments
- Validate timezone config at load time, not at schedule computation time
When it happens
Trigger: Calling assertAutomationTimezone (directly or via automationOccurrences) with a string that is not a valid IANA zone — misspelled names, 'UTC+2'-style offsets, empty strings, legacy aliases unsupported by the runtime, or user-supplied config values.
Common situations: Storing user-entered timezone strings from a settings UI; using fixed offset strings like 'GMT+1' instead of 'Europe/Paris'; environments (old Node, minimal ICU) lacking full tzdata so valid zones fail; locale-dependent aliases.
Related errors
- DEN_API_PUBLIC_URL cannot contain credentials, a query strin
- Manual OIDC configuration requires authorization, token, and
- ${name} must be a safe integer greater than or equal to ${mi
- An enterprise MCP server URL must use HTTP or HTTPS.
- An enterprise MCP server URL cannot contain a fragment.
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/1463a08e52a7a03c.
Report an issue: GitHub.