temporalio/temporal · error
%s Start is not in range [%d-%d]
Error message
%s Start is not in range [%d-%d]
What it means
makeRange parses one cron-style field (e.g. day-of-week) into a numeric range. When the part contains a dash (a range like '5-10'), parseValue validates the start against [minVal,maxVal]; if it fails (out-of-range value, or a value that fails the field's parse mode, e.g. non-numeric text where a name is not allowed), this error is returned naming the field and allowed bounds.
Source
Thrown at service/worker/scheduler/calendar.go:461
}
hasStep = true
}
start, end := minVal, maxVal
if part != "*" {
if strings.Contains(part, "-") {
// Only a single dash is allowed to denote a range (e.g. "1-5").
// Inputs with multiple dashes like "1-5-7" should raise the
// canonical "too many dashes" error expected by tests.
if strings.Count(part, "-") > 1 { // no negative numbers are expected in spec
return nil, fmt.Errorf("%s has too many dashes", field)
}
rangeParts := strings.SplitN(part, "-", 2)
if len(rangeParts) != 2 {
return nil, fmt.Errorf("%s has too many dashes", field)
}
if start, err = parseValue(rangeParts[0], minVal, maxVal, parseMode); err != nil {
return nil, fmt.Errorf("%s Start is not in range [%d-%d]", field, minVal, maxVal)
}
if end, err = parseValue(rangeParts[1], start, maxVal, parseMode); err != nil {
return nil, fmt.Errorf("%s End is before Start or not in range [%d-%d]", field, minVal, maxVal)
}
} else {
if start, err = parseValue(part, minVal, maxVal, parseMode); err != nil {
return nil, fmt.Errorf("%s is not in range [%d-%d]", field, minVal, maxVal)
}
if !hasStep {
// if / is present, a single value is treated as that value to the
// end. otherwise a single value is just the single value.
end = start
}
}
}
// Special handling for Sunday: Turn "7" into "0", which may require an extra range.
// Consider some cases:
// 0-7 or 1-7 can turn into 0-6View on GitHub (pinned to bde624efd1)
Solutions
- Check the start value of the range is within the printed [min-max] bounds for that field and fix it
- If using textual names, switch to a spec type that accepts names (e.g. CalendarSpec dayOfWeek strings) or use numeric values
- Catch the error and surface it as a user-facing schedule-validation message before creating the Schedule
Example fix
// before
calendar := &schedule.CalendarSpec{Hour: "25-30"}
// after
calendar := &schedule.CalendarSpec{Hour: "0-23"} Defensive patterns
Strategy: validation
Validate before calling
func validCronRangeStart(part string, min, max int) error {
i := strings.Index(part, "-")
if i <= 0 { return nil }
v, err := strconv.Atoi(part[:i])
if err != nil || v < min || v > max {
return fmt.Errorf("range start %q must be %d-%d", part[:i], min, max)
}
return nil
} Prevention
- Use schedule.Spec structs with typed ints rather than hand-written cron strings
- Test schedule parsing in unit tests before deploying schedule definitions
- Keep each field's documented min/max bounds at hand when writing ranges
When it happens
Trigger: Calling makeRange (via calendar spec parsing in a Scheduler/CalendarSpec workflow) with a range expression whose start bound is invalid, e.g. 'mon-sun' where month names are not accepted for that field, '60-70' for a minutes field (0-59), or a negative/out-of-bounds number like '99-100'.
Common situations: Hand-written cron-like schedule strings with typos; copying a cron expression between fields with different bounds (hour vs day-of-month); using textual names (MON, JAN) in fields that only accept numbers under the current parse mode.
Related errors
- %s End is before Start or not in range [%d-%d]
- %s is not in range [%d-%d]
- out of range
- conflicting timezone names
- ${errs}
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/4cc92e2ffbfb6ba3.
Report an issue: GitHub.