temporalio/temporal · error

Unable to merge scope with range %v with range %v by range

Error message

Unable to merge scope with range %v with range %v by range

What it means

Scope.MergeByRange panics when the incoming scope cannot be merged by range: either the ranges are not adjacent/contiguous (Range.CanMerge fails) or the predicates differ (predicates must be equal for a range merge). Merging by range is only valid for contiguous ranges carrying the same predicate.

Source

Thrown at service/history/queues/scope.go:74

	failScope := NewScope(
		s.Range,
		tasks.AndPredicates(s.Predicate, predicates.Not(predicate)),
	)
	return passScope, failScope
}

func (s *Scope) CanMergeByRange(
	incomingScope Scope,
) bool {
	return s.Range.CanMerge(incomingScope.Range) &&
		s.Predicate.Equals(incomingScope.Predicate)
}

func (s *Scope) MergeByRange(
	incomingScope Scope,
) Scope {
	if !s.CanMergeByRange(incomingScope) {
		panic(fmt.Sprintf("Unable to merge scope with range %v with range %v by range", s.Range, incomingScope.Range))
	}

	return NewScope(s.Range.Merge(incomingScope.Range), s.Predicate)
}

func (s *Scope) CanMergeByPredicate(
	incomingScope Scope,
) bool {
	return s.Range.Equals(incomingScope.Range)
}

func (s *Scope) MergeByPredicate(
	incomingScope Scope,
) Scope {
	if !s.CanMergeByPredicate(incomingScope) {
		panic(fmt.Sprintf("Unable to merge scope with range %v with range %v by predicate", s.Range, incomingScope.Range))
	}

View on GitHub (pinned to bde624efd1)

Solutions

  1. Check s.CanMergeByRange(incoming) first and skip merging when false
  2. If predicates differ but ranges are identical, use MergeByPredicate instead
  3. If ranges have a gap, merge the intermediate scope(s) first or keep them separate

Example fix

// before
merged := s.MergeByRange(incoming) // panics: predicate mismatch or non-contiguous

// after
var merged Scope
if s.CanMergeByRange(incoming) {
  merged = s.MergeByRange(incoming)
} else {
  merged = s // keep scopes separate
}
Defensive patterns

Strategy: validation

Validate before calling

if s.CanMergeByRange(incoming) {
  merged = s.MergeByRange(incoming)
}

Prevention

When it happens

Trigger: Calling s.MergeByRange(incoming) where incoming.Range does not touch s.Range (gap or overlap), or where incoming.Predicate differs from s.Predicate; calling on scopes split with different predicates.

Common situations: Compaction code merging scopes whose predicates were refined differently; merging non-adjacent ranges after manual key arithmetic; upgraded code changing predicate definitions so Equals fails.

Related errors


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