{"record":{"id":"408aca55a7b60f71","repo":"temporalio/temporal","slug":"s-has-too-many-dashes","errorCode":null,"errorMessage":"%s has too many dashes","messagePattern":"(.+?) has too many dashes","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"service/worker/scheduler/calendar.go","lineNumber":454,"sourceCode":"\t\t\tpart = skipParts[0]\n\t\t\tstep, err = strconv.Atoi(skipParts[1])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif step < 1 {\n\t\t\t\treturn nil, fmt.Errorf(\"%s has invalid Step\", field)\n\t\t\t}\n\t\t\thasStep = true\n\t\t}\n\n\t\tstart, end := minVal, maxVal\n\t\tif part != \"*\" {\n\t\t\tif strings.Contains(part, \"-\") {\n\t\t\t\t// Only a single dash is allowed to denote a range (e.g. \"1-5\").\n\t\t\t\t// Inputs with multiple dashes like \"1-5-7\" should raise the\n\t\t\t\t// canonical \"too many dashes\" error expected by tests.\n\t\t\t\tif strings.Count(part, \"-\") > 1 { // no negative numbers are expected in spec\n\t\t\t\t\treturn nil, fmt.Errorf(\"%s has too many dashes\", field)\n\t\t\t\t}\n\t\t\t\trangeParts := strings.SplitN(part, \"-\", 2)\n\t\t\t\tif len(rangeParts) != 2 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"%s has too many dashes\", field)\n\t\t\t\t}\n\t\t\t\tif start, err = parseValue(rangeParts[0], minVal, maxVal, parseMode); err != nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"%s Start is not in range [%d-%d]\", field, minVal, maxVal)\n\t\t\t\t}\n\t\t\t\tif end, err = parseValue(rangeParts[1], start, maxVal, parseMode); err != nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"%s End is before Start or not in range [%d-%d]\", field, minVal, maxVal)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif start, err = parseValue(part, minVal, maxVal, parseMode); err != nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"%s is not in range [%d-%d]\", field, minVal, maxVal)\n\t\t\t\t}\n\t\t\t\tif !hasStep {\n\t\t\t\t\t// if / is present, a single value is treated as that value to the\n\t\t\t\t\t// end. otherwise a single value is just the single value.","sourceCodeStart":436,"sourceCodeEnd":472,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/service/worker/scheduler/calendar.go#L436-L472","documentation":"In a cron field part that is not \"*\", at most one '-' (denoting a range like \"1-5\") is allowed because negative numbers are not valid in this spec. A part containing two or more dashes, e.g. \"1-5-7\", makes makeRange return this canonical error naming the field.","triggerScenarios":"A spec field part like \"1-5-7\" or \"MON-WED-FRI\" in the day-of-week field is passed to schedule parsing.","commonSituations":"Users chaining multiple ranges with dashes instead of commas (correct form: \"1-5,7\"); copy-paste errors; confusion with other cron dialects that support lists differently.","solutions":["Express multiple ranges/ranges+values as a comma-separated list: \"1-5-7\" → \"1-5,7\".","Validate the cron expression before submission.","Check the field name in the error to find the offending part.","If the intent was an enumeration, use commas, not dashes."],"exampleFix":"// before\nspec := \"1-5-7\"\n// after\nspec := \"1-5,7\"","handlingStrategy":"validation","validationCode":"func validRangePart(part string) bool {\n    return strings.Count(part, \"-\") <= 1\n}\nif !validRangePart(dayPart) {\n    return errors.New(\"use commas to combine multiple ranges, e.g. 1-5,7\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Teach users that multiple ranges are comma-separated, not dash-chained.","Validate each comma-separated cron part against ^\\*?([^-]+(-[^-]+)?)(/\\d+)?$ style patterns.","Add parsing tests covering '1-5-7' style inputs to fail fast at config load."],"tags":["go","scheduler","cron","validation","parsing"],"backgroundTag":"invalid-cron-spec","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}