temporalio/temporal · error
Unable to split queue slice with range %v at %v
Error message
Unable to split queue slice with range %v at %v
What it means
SliceImpl.SplitByRange panics when CanSplitByRange(key) is false, i.e. the split key is not strictly inside the slice's scope range. Splitting a slice divides its task trackers and iterators into two halves; a key outside the range would produce empty or invalid halves.
Source
Thrown at service/history/queues/slice.go:103
metricsHandler: metricsHandler,
}
s.ensurePredicateSizeLimit()
return s
}
func (s *SliceImpl) Scope() Scope {
s.stateSanityCheck()
return s.scope
}
func (s *SliceImpl) CanSplitByRange(key tasks.Key) bool {
s.stateSanityCheck()
return s.scope.CanSplitByRange(key)
}
func (s *SliceImpl) SplitByRange(key tasks.Key) (left Slice, right Slice) {
if !s.CanSplitByRange(key) {
panic(fmt.Sprintf("Unable to split queue slice with range %v at %v", s.scope.Range, key))
}
return s.splitByRange(key)
}
func (s *SliceImpl) splitByRange(key tasks.Key) (left *SliceImpl, right *SliceImpl) {
leftScope, rightScope := s.scope.SplitByRange(key)
leftTaskTracker, rightTaskTracker := s.split(leftScope, rightScope)
leftIterators := make([]Iterator, 0, len(s.iterators)/2)
rightIterators := make([]Iterator, 0, len(s.iterators)/2)
for _, iter := range s.iterators {
iterRange := iter.Range()
if leftScope.Range.ContainsRange(iterRange) {
leftIterators = append(leftIterators, iter)
continue
}View on GitHub (pinned to bde624efd1)
Solutions
- Call slice.CanSplitByRange(key) first and handle the false case without splitting
- Choose the split key strictly within the slice's current scope range (e.g. midpoint)
- Re-read the slice's Scope() before splitting rather than caching an old range
Example fix
// before
left, right := slice.SplitByRange(key) // panics if key outside range
// after
if slice.CanSplitByRange(key) {
left, right = slice.SplitByRange(key)
} Defensive patterns
Strategy: validation
Validate before calling
if slice.CanSplitByRange(key) {
left, right = slice.SplitByRange(key)
} Prevention
- Always call CanSplitByRange first
- Derive split keys from the slice's current Scope(), not cached ranges
- Handle already-consumed slices without splitting
When it happens
Trigger: Calling slice.SplitByRange(key) where key <= scope.Range.InclusiveMin or key >= scope.Range.ExclusiveMax; splitting an already-cleared or empty slice; using a key derived from a different slice's range.
Common situations: Queue load balancing choosing split points from stale metadata; splitting a slice that was already fully consumed; key comparison mistakes between inclusive/exclusive bounds.
Related errors
- Unable to split scope with range %v at %v
- Unable to split iterator with range %v at %v
- Unable to split range %v at %v
- Can not append slice to existing list of slices, incoming sl
- Found overlapping incoming slices, left slice range: %v, rig
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/4d0d8e621f3be769.
Report an issue: GitHub.