temporalio/temporal · error
Unable to compact queue slice of type %T with type %T
Error message
Unable to compact queue slice of type %T with type %T
What it means
SliceImpl.CompactWithSlice panics if the incoming slice cannot be type-asserted to *SliceImpl. Compaction merges two slices' executable trackers, iterators, and predicates (ORed) into one slice covering the union range, and requires concrete SliceImpl internals. Like the merge case, it rejects any foreign Slice implementation.
Source
Thrown at service/history/queues/slice.go:282
if len(iterators) == 0 {
return []Iterator{iterator}
}
size := len(iterators)
if iterators[size-1].CanMerge(iterator) {
iterators[size-1] = iterators[size-1].Merge(iterator)
return iterators
}
return append(iterators, iterator)
}
func (s *SliceImpl) CompactWithSlice(slice Slice) Slice {
s.stateSanityCheck()
incomingSlice, ok := slice.(*SliceImpl)
if !ok {
panic(fmt.Sprintf("Unable to compact queue slice of type %T with type %T", s, slice))
}
incomingSlice.stateSanityCheck()
compactedScope := NewScope(
NewRange(
tasks.MinKey(s.scope.Range.InclusiveMin, incomingSlice.scope.Range.InclusiveMin),
tasks.MaxKey(s.scope.Range.ExclusiveMax, incomingSlice.scope.Range.ExclusiveMax),
),
tasks.OrPredicates(s.scope.Predicate, incomingSlice.scope.Predicate),
)
compactedTaskTracker := s.merge(incomingSlice.executableTracker)
compactedIterators := s.mergeIterators(incomingSlice)
s.destroy()
incomingSlice.destroy()
return s.newSlice(View on GitHub (pinned to bde624efd1)
Solutions
- Pass only concrete *SliceImpl values to CompactWithSlice
- Unwrap decorators/wrappers to the underlying *SliceImpl before compacting
- Replace test mocks of Slice with real slices built via the package constructor
Example fix
// before
compact := s.CompactWithSlice(wrapperSlice) // panics: not *SliceImpl
// after
impl, ok := wrapperSlice.(*queues.SliceImpl)
if !ok {
return nil
}
compact := s.CompactWithSlice(impl) Defensive patterns
Strategy: type-guard
Validate before calling
if _, ok := other.(*queues.SliceImpl); !ok {
return nil // cannot compact non-SliceImpl
} Type guard
func asSliceImpl(s queues.Slice) (*queues.SliceImpl, bool) {
impl, ok := s.(*queues.SliceImpl)
return impl, ok
} Try / catch
func safeCompact(s *queues.SliceImpl, other queues.Slice) (result queues.Slice) {
defer func() {
if r := recover(); r != nil {
result = nil
}
}()
return s.CompactWithSlice(other)
} Prevention
- Pass only *SliceImpl values to CompactWithSlice
- Unwrap any instrumentation wrapper to the concrete slice first
- Keep slice types uniform across reader/compaction code paths
When it happens
Trigger: Calling CompactWithSlice with a wrapper/mock implementing Slice but not *SliceImpl; passing a typed-nil or non-nil interface holding another implementation; custom slices introduced for testing or instrumentation.
Common situations: Mock slices in unit tests of compaction logic; decorators around slices for observability; refactors that changed the concrete type while older call sites passed the old wrapper.
Related errors
- Unable to merge queue slice of type %T with type %T
- Can not append slice to existing list of slices, incoming sl
- Found overlapping incoming slices, left slice range: %v, rig
- reader with ID %v already exists
- Unable to split scope with range %v at %v
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/86d91cd6a2f2d410.
Report an issue: GitHub.