temporalio/temporal · error
Found key with non-zero pending task count but has no corres
Error message
Found key with non-zero pending task count but has no correspoding Slice
What it means
This panic fires in findSliceToClear when the priority queue reports a key with a non-zero pending task count, but the internal slicesPerKey map has no Slice registered for that key. It is an internal invariant violation in the queue's bookkeeping: the pending-task counter and the slice registry are out of sync. The typo "correspoding" is in the original panic message.
Source
Thrown at service/history/queues/action_pending_task_count.go:140
// order key by # of pending tasks
keys := make([]any, 0, len(a.tasksPerKey))
for key, keyPendingTasks := range a.tasksPerKey {
currentPendingTasks += keyPendingTasks
keys = append(keys, key)
}
pq := collection.NewPriorityQueueWithItems(
func(this, that any) bool {
return a.tasksPerKey[this] > a.tasksPerKey[that]
},
keys,
)
for currentPendingTasks > targetPendingTasks && !pq.IsEmpty() {
key := pq.Remove()
sliceList := a.slicesPerKey[key]
if len(sliceList) == 0 {
panic("Found key with non-zero pending task count but has no correspoding Slice")
}
// pop the first slice in the list
sliceToClear := sliceList[0]
sliceList = sliceList[1:]
a.slicesPerKey[key] = sliceList
tasksCleared := a.pendingTasksPerKeyPerSlice[sliceToClear][key]
a.tasksPerKey[key] -= tasksCleared
currentPendingTasks -= tasksCleared
if a.tasksPerKey[key] > 0 {
pq.Add(key)
}
a.keysToClearPerSlice[sliceToClear] = append(a.keysToClearPerSlice[sliceToClear], key)
}
}
View on GitHub (pinned to bde624efd1)
Solutions
- Find where slices are removed/cleared from a.slicesPerKey and ensure the corresponding pending task count key is removed from the priority queue at the same time
- Verify the key type used for pq and slicesPerKey matches exactly (task key comparison semantics)
- Upgrade to a version containing the fix if this is a known temporal history invariant bug
- Capture the key, pending count, and pq state in logs before the panic to file a reproducible report
Example fix
// before
sliceList := a.slicesPerKey[key]
if len(sliceList) == 0 {
panic("Found key with non-zero pending task count but has no correspoding Slice")
}
// after
sliceList := a.slicesPerKey[key]
if len(sliceList) == 0 {
a.logger.Error("invariant violated: key in pending-task queue has no slices",
tag.Key(key), tag.PendingTaskCount(currentPendingTasks))
continue
} Defensive patterns
Strategy: validation
Validate before calling
if sliceList, ok := action.slicesPerKey[key]; !ok || len(sliceList) == 0 {
// do not invoke the clear path for this key
return
} Prevention
- Always update pq and slicesPerKey in the same code path
- Write an invariant-check unit test that clears slices and asserts counter/registry consistency
- Never mutate queue bookkeeping outside the action's Run method
When it happens
Trigger: Run calls findSliceToClear to reduce pending tasks; pq.Remove() returns a key whose slicesPerKey entry is empty or missing because slices were cleared/removed without decrementing their pending task counts, or a slice was registered under a different key.
Common situations: Custom or modified queue actions that clear slices directly; bugs in Slice removal paths that forget to update slicesPerKey or the pending task counter; race conditions if the action is used outside the single-threaded context it was designed for.
Related errors
- expect at least one reservation
- unknown task predicate type: %T
- unknown persistence task predicate type: %v
- panic(e)
- Iterator encountered Next call when there is no next item
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/d23daebf0adf2183.
Report an issue: GitHub.