{"record":{"id":"a62bf07abe8599c9","repo":"temporalio/temporal","slug":"unable-to-merge-scope-with-range-v-with-range-v","errorCode":null,"errorMessage":"Unable to merge scope with range %v with range %v by range","messagePattern":"Unable to merge scope with range (.+?) with range (.+?) by range","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/history/queues/scope.go","lineNumber":74,"sourceCode":"\tfailScope := NewScope(\n\t\ts.Range,\n\t\ttasks.AndPredicates(s.Predicate, predicates.Not(predicate)),\n\t)\n\treturn passScope, failScope\n}\n\nfunc (s *Scope) CanMergeByRange(\n\tincomingScope Scope,\n) bool {\n\treturn s.Range.CanMerge(incomingScope.Range) &&\n\t\ts.Predicate.Equals(incomingScope.Predicate)\n}\n\nfunc (s *Scope) MergeByRange(\n\tincomingScope Scope,\n) Scope {\n\tif !s.CanMergeByRange(incomingScope) {\n\t\tpanic(fmt.Sprintf(\"Unable to merge scope with range %v with range %v by range\", s.Range, incomingScope.Range))\n\t}\n\n\treturn NewScope(s.Range.Merge(incomingScope.Range), s.Predicate)\n}\n\nfunc (s *Scope) CanMergeByPredicate(\n\tincomingScope Scope,\n) bool {\n\treturn s.Range.Equals(incomingScope.Range)\n}\n\nfunc (s *Scope) MergeByPredicate(\n\tincomingScope Scope,\n) Scope {\n\tif !s.CanMergeByPredicate(incomingScope) {\n\t\tpanic(fmt.Sprintf(\"Unable to merge scope with range %v with range %v by predicate\", s.Range, incomingScope.Range))\n\t}\n","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/service/history/queues/scope.go#L56-L92","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check s.CanMergeByRange(incoming) first and skip merging when false","If predicates differ but ranges are identical, use MergeByPredicate instead","If ranges have a gap, merge the intermediate scope(s) first or keep them separate"],"exampleFix":"// before\nmerged := s.MergeByRange(incoming) // panics: predicate mismatch or non-contiguous\n\n// after\nvar merged Scope\nif s.CanMergeByRange(incoming) {\n  merged = s.MergeByRange(incoming)\n} else {\n  merged = s // keep scopes separate\n}","handlingStrategy":"validation","validationCode":"if s.CanMergeByRange(incoming) {\n  merged = s.MergeByRange(incoming)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Gate MergeByRange behind CanMergeByRange","Only range-merge scopes that carry identical predicates","Fall back to keeping scopes separate when ranges are not contiguous"],"tags":["go","history-service","task-queue","range-merge","panic"],"backgroundTag":"non-contiguous-range-merge","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}