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

  1. Call slice.CanSplitByRange(key) first and handle the false case without splitting
  2. Choose the split key strictly within the slice's current scope range (e.g. midpoint)
  3. 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

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


AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01). Data as JSON: /api/errors/4d0d8e621f3be769. Report an issue: GitHub.