{"record":{"id":"d50885bff1c94e69","repo":"temporalio/temporal","slug":"found-overlapping-incoming-slices-left-slice-rang","errorCode":null,"errorMessage":"Found overlapping incoming slices, left slice range: %v, right slice range: %v","messagePattern":"Found overlapping incoming slices, left slice range: (.+?), right slice range: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/history/queues/reader.go","lineNumber":573,"sourceCode":"\n\tmergedSlices := lastSlice.MergeWithSlice(incomingSlice)\n\tslices.Remove(lastElement)\n\tfor _, mergedSlice := range mergedSlices {\n\t\tslices.PushBack(mergedSlice)\n\t}\n}\n\nfunc validateSlicesOrderedDisjoint(\n\tslices []Slice,\n) {\n\tif len(slices) <= 1 {\n\t\treturn\n\t}\n\n\tfor idx, slice := range slices[:len(slices)-1] {\n\t\tnextSlice := slices[idx+1]\n\t\tif slice.Scope().Range.ExclusiveMax.CompareTo(nextSlice.Scope().Range.InclusiveMin) > 0 {\n\t\t\tpanic(fmt.Sprintf(\n\t\t\t\t\"Found overlapping incoming slices, left slice range: %v, right slice range: %v\",\n\t\t\t\tslice.Scope().Range,\n\t\t\t\tnextSlice.Scope().Range,\n\t\t\t))\n\t\t}\n\t}\n}\n","sourceCodeStart":555,"sourceCodeEnd":581,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/service/history/queues/reader.go#L555-L581","documentation":"validateSlicesOrderedDisjoint panics if any adjacent pair in the incoming slice list overlaps: slice[i].Range.ExclusiveMax > slice[i+1].Range.InclusiveMin. It is called by MergeSlices and AppendSlices as a precondition that the caller passed an ordered, disjoint set of slices. The invariant check guarantees the merge/append algorithms can assume sorted input.","triggerScenarios":"Calling AppendSlices(s1, s2) or MergeSlices(s1, s2) where an earlier slice's ExclusiveMax exceeds a later slice's InclusiveMin; passing unsorted slices where sorting happens to also produce an overlap.","commonSituations":"Constructing slices from a DB query that was not ordered by task_id; splitting/merging logic in custom task processing that reassembles slices in wrong order; after version upgrades that changed key encoding.","solutions":["Sort the slice list by Scope().Range.InclusiveMin before passing it in","Verify the producer of these slices (DB query, split logic) returns ordered disjoint ranges; add an ORDER BY on task_id/task visibility columns","Merge overlapping slices yourself (or via SliceImpl.MergeWithSlice) so the final list is disjoint before calling the API"],"exampleFix":"// before\nreader.AppendSlices(sliceB, sliceA) // unsorted or overlapping\n\n// after\nsort.Slice(slices, func(i, j int) bool {\n  return slices[i].Scope().Range.InclusiveMin.CompareTo(slices[j].Scope().Range.InclusiveMin) < 0\n})\n// ensure disjoint, then:\nreader.AppendSlices(slices...)","handlingStrategy":"validation","validationCode":"func orderedDisjoint(slices []queues.Slice) bool {\n  for i := 0; i < len(slices)-1; i++ {\n    if slices[i].Scope().Range.ExclusiveMax.CompareTo(slices[i+1].Scope().Range.InclusiveMin) > 0 {\n      return false\n    }\n  }\n  return true\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Sort by Scope().Range.InclusiveMin immediately after loading slices from any source","Ensure DB queries backing slices ORDER BY the task key columns","Add a cheap orderedDisjoint assertion in tests that build slice batches"],"tags":["go","history-service","task-queue","slice-ordering","panic"],"backgroundTag":"slice-range-overlap","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}