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

  1. Pass only concrete *SliceImpl values to CompactWithSlice
  2. Unwrap decorators/wrappers to the underlying *SliceImpl before compacting
  3. 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

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


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