{"record":{"id":"196041c5cf8e64e8","repo":"temporalio/temporal","slug":"conflicting-timezone-names","errorCode":null,"errorMessage":"conflicting timezone names","messagePattern":"conflicting timezone names","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/worker/scheduler/calendar.go","lineNumber":54,"sourceCode":"\n\t// max length of one calendar comment field\n\tmaxCommentLen = 200\n)\n\nconst (\n\t// Modes for parsing range strings: all modes accept decimal integers\n\tparseModeInt parseMode = iota\n\t// parseModeYear is like parseModeInt but returns an empty range for the default\n\tparseModeYear\n\t// parseModeMonth also accepts month name prefixes (at least three letters)\n\tparseModeMonth\n\t// parseModeDow also accepts day-of-week prefixes (at least two letters)\n\tparseModeDow\n)\n\nvar (\n\terrOutOfRange               = errors.New(\"out of range\")\n\terrConflictingTimezoneNames = errors.New(\"conflicting timezone names\")\n\n\tmonthStrings = []string{\n\t\t\"january\",\n\t\t\"february\",\n\t\t\"march\",\n\t\t\"april\",\n\t\t\"may\",\n\t\t\"june\",\n\t\t\"july\",\n\t\t\"august\",\n\t\t\"september\",\n\t\t\"october\",\n\t\t\"november\",\n\t\t\"december\",\n\t}\n\n\tdowStrings = []string{\n\t\t\"sunday\",","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/service/worker/scheduler/calendar.go#L36-L72","documentation":"errConflictingTimezoneNames is returned by canonicalizeSpec when a calendar/cron spec carries two different timezone designations — for example a TZ= prefix on a cron string plus a TimeZoneName on the structured spec, or different IANA names in nested specs. The scheduler cannot pick a single zone deterministically, so parsing fails.","triggerScenarios":"Updating a schedule while supplying a cron string with TZ=/CRON_TZ= AND setting a separate timezone field on the structured spec to a different name; programmatic schedule updates that copy an old timezone field while changing the cron prefix.","commonSituations":"Migrating from cron-string schedules to structured CalendarSpec and leaving both timezone sources set; tools that append CRON_TZ without checking existing spec timezone; hand-edited schedule configs after a datacenter/region change.","solutions":["Remove one of the two timezone declarations — keep either the TZ=/CRON_TZ= prefix or the spec's timezone field, not both.","If both are set, make them identical is not allowed; clear the legacy field and re-apply the update.","Use temporal schedule update describe output to confirm which timezone the schedule currently uses before editing.","Standardize on one timezone mechanism (usually the structured spec's timezone name) across automation tooling."],"exampleFix":"// before\ncron := \"TZ=America/New_York 0 9 * * *\"\nspec.TimeZoneName = \"Europe/London\" // conflict\n// after\ncron := \"0 9 * * *\"\nspec.TimeZoneName = \"America/New_York\"","handlingStrategy":"validation","validationCode":"func checkSingleTimezone(cron string, tzName string) error {\n\thasTZPrefix := strings.HasPrefix(cron, \"TZ=\") || strings.HasPrefix(cron, \"CRON_TZ=\")\n\tif hasTZPrefix && tzName != \"\" {\n\t\treturn errors.New(\"spec sets timezone in both cron prefix and spec field\")\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"conflicting timezone names\") {\n\t// clear one timezone source and re-apply the schedule update\n}","preventionTips":["Standardize on one timezone mechanism (structured spec TimeZoneName) across tooling.","When migrating cron strings to structured specs, strip TZ=/CRON_TZ= prefixes.","Run `temporal schedule describe` before updates to see the current timezone source."],"tags":["scheduler","timezone","validation","go"],"backgroundTag":"conflicting-timezone","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}