{"record":{"id":"e6e123d8aa9d83d5","repo":"temporalio/temporal","slug":"unable-to-merge-queue-slice-of-type-t-with-type","errorCode":null,"errorMessage":"Unable to merge queue slice of type %T with type %T","messagePattern":"Unable to merge queue slice of type %T with type %T","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/history/queues/slice.go","lineNumber":176,"sourceCode":"\nfunc (s *SliceImpl) CanMergeWithSlice(slice Slice) bool {\n\ts.stateSanityCheck()\n\n\treturn s != slice && s.scope.Range.CanMerge(slice.Scope().Range)\n}\n\nfunc (s *SliceImpl) MergeWithSlice(slice Slice) []Slice {\n\tif s.scope.Range.InclusiveMin.CompareTo(slice.Scope().Range.InclusiveMin) > 0 {\n\t\treturn slice.MergeWithSlice(s)\n\t}\n\n\tif !s.CanMergeWithSlice(slice) {\n\t\tpanic(fmt.Sprintf(\"Unable to merge queue slice having scope %v with slice having scope %v\", s.scope, slice.Scope()))\n\t}\n\n\tincomingSlice, ok := slice.(*SliceImpl)\n\tif !ok {\n\t\tpanic(fmt.Sprintf(\"Unable to merge queue slice of type %T with type %T\", s, slice))\n\t}\n\n\tif s.scope.CanMergeByRange(incomingSlice.scope) {\n\t\treturn []Slice{s.mergeByRange(incomingSlice)}\n\t}\n\n\tmergedSlices := make([]Slice, 0, 3)\n\tcurrentLeftSlice, currentRightSlice := s.splitByRange(incomingSlice.Scope().Range.InclusiveMin)\n\tmergedSlices = appendMergedSlice(mergedSlices, currentLeftSlice)\n\n\tif currentRightMax := currentRightSlice.Scope().Range.ExclusiveMax; incomingSlice.CanSplitByRange(currentRightMax) {\n\t\tleftIncomingSlice, rightIncomingSlice := incomingSlice.splitByRange(currentRightMax)\n\t\tmergedMidSlice := currentRightSlice.mergeByPredicate(leftIncomingSlice)\n\t\tmergedSlices = appendMergedSlice(mergedSlices, mergedMidSlice)\n\t\tmergedSlices = appendMergedSlice(mergedSlices, rightIncomingSlice)\n\t} else {\n\t\tcurrentMidSlice, currentRightSlice := currentRightSlice.splitByRange(incomingSlice.Scope().Range.ExclusiveMax)\n\t\tmergedMidSlice := currentMidSlice.mergeByPredicate(incomingSlice)","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/service/history/queues/slice.go#L158-L194","documentation":"SliceImpl.MergeWithSlice also panics if the incoming slice cannot be type-asserted to *SliceImpl. The merge implementation needs concrete SliceImpl internals (scope, iterators, executable tracker); any other implementation of the Slice interface cannot be merged. This guards against mixing slice implementations.","triggerScenarios":"Passing a custom or wrapper type implementing the Slice interface (not *SliceImpl) to MergeWithSlice; passing a nil Slice with a non-nil interface value; wrapping slices in decorators for instrumentation.","commonSituations":"Test code supplying mock Slice implementations; production wrappers adding metrics/logging around slices; DI swaps introducing an alternate slice type.","solutions":["Pass only concrete *SliceImpl values created via NewSlice/NewSliceImpl","Unwrap any decorator/wrapper to the underlying *SliceImpl before merging","In tests, use the real slice constructor instead of mock Slice implementations"],"exampleFix":"// before\nslice.MergeWithSlice(mockSlice) // panics: not *SliceImpl\n\n// after\nimpl, ok := wrapped.(*queues.SliceImpl)\nif !ok {\n  return nil // or unwrap the decorator\n}\nresult := slice.MergeWithSlice(impl)","handlingStrategy":"type-guard","validationCode":"if _, ok := other.(*queues.SliceImpl); !ok {\n  return nil // or unwrap; cannot merge non-SliceImpl\n}","typeGuard":"func asSliceImpl(s queues.Slice) (*queues.SliceImpl, bool) {\n  impl, ok := s.(*queues.SliceImpl)\n  return impl, ok\n}","tryCatchPattern":"func safeMerge(s *queues.SliceImpl, other queues.Slice) (result []queues.Slice) {\n  defer func() {\n    if r := recover(); r != nil {\n      result = nil\n    }\n  }()\n  return s.MergeWithSlice(other)\n}","preventionTips":["Only construct slices via the package's constructors","Unwrap wrappers before handing slices to merge/compact APIs","Avoid mocking the Slice interface in tests; use real SliceImpl"],"tags":["go","history-service","task-queue","type-assertion","panic"],"backgroundTag":"slice-type-mismatch","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}