temporalio/temporal · error
Cannot peek item because priority queue is empty
Error message
Cannot peek item because priority queue is empty
What it means
Peek() on priorityQueueImpl returns the top item but the queue is a strict data structure: calling Peek on an empty queue is a programming error, so the library panics instead of returning a zero value. This protects callers from silently processing a zero-value item that could corrupt ordering logic.
Source
Thrown at common/collection/priority_queue.go:43
// PriorityQueue will take ownership of the passed in items,
// so caller should stop modifying it.
// The complexity is O(n) where n is the number of items
func NewPriorityQueueWithItems[T any](
compareLess func(this T, other T) bool,
items []T,
) Queue[T] {
pq := &priorityQueueImpl[T]{
compareLess: compareLess,
items: items,
}
heap.Init(pq)
return pq
}
// Peek returns the top item of the priority queue
func (pq *priorityQueueImpl[T]) Peek() T {
if pq.IsEmpty() {
panic("Cannot peek item because priority queue is empty")
}
return pq.items[0]
}
// Add push an item to priority queue
func (pq *priorityQueueImpl[T]) Add(item T) {
heap.Push(pq, item)
}
// Remove pop an item from priority queue
func (pq *priorityQueueImpl[T]) Remove() T {
return heap.Pop(pq).(T)
}
// IsEmpty indicate if the priority queue is empty
func (pq *priorityQueueImpl[T]) IsEmpty() bool {
return pq.Len() == 0
}View on GitHub (pinned to bde624efd1)
Solutions
- Check pq.IsEmpty() (or pq.Len() == 0) before calling Peek
- Restructure the drain loop to use the remove/pop operation's returned item instead of a Peek-then-Pop pair
- Guard concurrent producers/consumers so Peek is only reached when a size check and fill have both completed
Example fix
// before
item := pq.Peek()
// after
if pq.IsEmpty() {
return // or wait for items
}
item := pq.Peek() Defensive patterns
Strategy: validation
Validate before calling
if pq.Len() > 0 { _ = pq.Peek() } Prevention
- Check IsEmpty before Peek
- Use Pop-with-ok APIs in drain loops
When it happens
Trigger: Calling pq.Peek() when no items have been added via Add() or after all items were removed (e.g. after popping the last element).
Common situations: Startup ordering bugs where a consumer drains the queue faster than producers fill it; off-by-one drain loops calling Peek after the final Pop; retry logic that re-peeks after removal.
Related errors
- Current cluster name is empty
- Version increment <= 0 or > 2147483647
- <dynamic updateVersionToClusterName err>
- Current cluster is not specified in cluster info
- Master cluster is not specified in cluster info
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/c7d45f47572d6581.
Report an issue: GitHub.