{"record":{"id":"e4f48c8bd17940fb","repo":"temporalio/temporal","slug":"s-has-invalid-step","errorCode":null,"errorMessage":"%s has invalid Step","messagePattern":"(.+?) has invalid Step","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"service/worker/scheduler/calendar.go","lineNumber":442,"sourceCode":"\t\tif slashes > 1 {\n\t\t\t// Inputs like \"3/5/7\" should yield the canonical \"too many slashes\" error\n\t\t\t// (instead of a later strconv parse error) so tests get consistent results.\n\t\t\treturn nil, fmt.Errorf(\"%s has too many slashes\", field)\n\t\t}\n\t\tif slashes == 1 {\n\t\t\t// A single slash introduces an integer step.\n\t\t\tskipParts := strings.SplitN(part, \"/\", 2)\n\t\t\t// Count==1 guarantees len==2; only need to ensure the right side is non-empty.\n\t\t\tif skipParts[1] == \"\" { // e.g. \"5/\"\n\t\t\t\treturn nil, fmt.Errorf(\"%s missing step value\", field)\n\t\t\t}\n\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 {","sourceCodeStart":424,"sourceCodeEnd":460,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/service/worker/scheduler/calendar.go#L424-L460","documentation":"After parsing the step value following a '/', makeRange requires the step to be a positive integer (>= 1). A zero or negative step (e.g. \"*/0\" or \"1-5/-2\") yields this error naming the field, since a non-positive step would produce an empty or infinite range.","triggerScenarios":"Submitting a schedule spec field with a step of 0 or negative, like \"*/0\", \"0/0\", or \"1-5/0\"; often the result of arithmetic in generated specs (interval computed as 0).","commonSituations":"Configuration computed from a duration/interval variable that evaluated to 0; users misremembering cron syntax and using 0 as 'every'; template defaults not initialized.","solutions":["Use a step >= 1, e.g. \"*/0\" → \"*/1\" or \"*/5\".","Clamp computed interval values to a minimum of 1 before rendering the spec.","Validate spec inputs at the application boundary before creating the schedule.","Review which field the error names to pinpoint the bad part."],"exampleFix":"// before\nstep := intervalSeconds // could be 0\nspec := fmt.Sprintf(\"*/%d\", step)\n// after\nif step < 1 {\n    step = 1\n}\nspec := fmt.Sprintf(\"*/%d\", step)","handlingStrategy":"validation","validationCode":"step, err := strconv.Atoi(stepPart)\nif err != nil || step < 1 {\n    return errors.New(\"cron step must be a positive integer\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Clamp computed intervals to a minimum of 1 before embedding in specs.","Reject non-positive steps at the config boundary.","Document that 0 is not a valid cron step in your scheduling docs."],"tags":["go","scheduler","cron","validation"],"backgroundTag":"invalid-cron-spec","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}