temporalio/temporal · error
panic(e)
Error message
panic(e)
What it means
This deferred recover/re-panic wrapper around Executable.Execute ensures the done callback runs with false when the executable panics, then re-panics to preserve the original crash. The panic(e) is the deliberate re-throw, not a bug; the original panic could be any runtime error inside task execution.
Source
Thrown at service/history/queues/executable.go:969
if err != nil {
metrics.CircuitBreakerExecutableBlocked.With(e.metricsHandler).Record(1)
// Return a resource exhausted error to ensure that this task is retried less aggressively
// and does not go to the DLQ.
return fmt.Errorf(
"%w: %w",
serviceerror.NewResourceExhausted(
enumspb.RESOURCE_EXHAUSTED_CAUSE_CIRCUIT_BREAKER_OPEN,
"circuit breaker rejection",
),
err,
)
}
defer func() {
e := recover()
if e != nil {
doneCb(false)
panic(e)
}
}()
err = e.Executable.Execute()
var destinationDownErr *queueserrors.DestinationDownError
if errors.As(err, &destinationDownErr) {
err = destinationDownErr.Unwrap()
}
doneCb(destinationDownErr == nil)
return err
}
View on GitHub (pinned to bde624efd1)
Solutions
- Inspect the panic stack trace to identify which executable task processor panicked
- Fix the underlying nil/error path in the task's Execute implementation
- Wrap individual task execution with its own recover if panics from user data are expected
- Report to temporal maintainers if a stock task type panics on valid data
Defensive patterns
Strategy: try-catch
Try / catch
defer func() {
if r := recover(); r != nil {
logger.Error("task executable panicked", "panic", r, "stack", string(debug.Stack()))
}
}()
err = executable.Execute() Prevention
- Nil-check all task attributes before Execute
- Wrap third-party/untrusted task processing in recover boundaries
- Fuzz/validate incoming task payloads
- Always invoke completion callbacks via defer so panics cannot skip them
When it happens
Trigger: Any panic inside e.Executable.Execute() — nil pointer, index out of range, or a nested panic from task processing — causes the deferred func to invoke doneCb(false) and then re-panic with panic(e).
Common situations: Corrupt or unexpected task payloads triggering runtime panics in task processors; bugs in executable task handling code; crashes during rolling upgrades.
Related errors
- Found key with non-zero pending task count but has no corres
- unknown task predicate type: %T
- unknown persistence task predicate type: %v
- Iterator encountered Next call when there is no next item
- Unable to split iterator with range %v at %v
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/b5e7afc274fb0c87.
Report an issue: GitHub.