temporalio/temporal · warning
batch operation stats are not present in the memo
Error message
batch operation stats are not present in the memo
What it means
Returned by WorkflowHandler.getCompletedBatchOperationStats when the batch operation's stats payload is missing from the workflow memo. Completed batch operations record BatchOperationStats in the workflow's memo; if absent, the handler cannot decode and return stats for ListBatchOperations/DescribeBatchOperation responses.
Source
Thrown at service/frontend/workflow_handler.go:6305
if len(resp.GetPendingActivities()) > 0 {
hbdPayload := resp.GetPendingActivities()[0].HeartbeatDetails
var hbd batcher.HeartBeatDetails
err = payloads.Decode(hbdPayload, &hbd)
if err != nil {
return nil, err
}
batchOperationResp.TotalOperationCount = hbd.TotalEstimate
batchOperationResp.CompleteOperationCount = int64(hbd.SuccessCount)
batchOperationResp.FailureOperationCount = int64(hbd.ErrorCount)
}
}
return batchOperationResp, nil
}
func (wh *WorkflowHandler) getCompletedBatchOperationStats(memo map[string]*commonpb.Payload) (stats batcher.BatchOperationStats, err error) {
statsPayload, ok := memo[batcher.BatchOperationStatsMemo]
if !ok {
return stats, errors.New("batch operation stats are not present in the memo")
}
err = payload.Decode(statsPayload, &stats)
return stats, err
}
func (wh *WorkflowHandler) ListBatchOperations(
ctx context.Context,
request *workflowservice.ListBatchOperationsRequest,
) (_ *workflowservice.ListBatchOperationsResponse, retError error) {
defer log.CapturePanic(wh.logger, &retError)
if err := wh.versionChecker.ClientSupported(ctx); err != nil {
return nil, err
}
if request == nil {
return nil, errRequestNotSet
}View on GitHub (pinned to bde624efd1)
Solutions
- Upgrade to a server version that writes batch operation stats to the memo and re-run the batch operation if stats are required
- Handle the error gracefully in tooling: show batch result status without stats for legacy batch workflows
- Do not modify batch workflow memo via UpdateWorkflow while a batch is running
Defensive patterns
Strategy: fallback
Validate before calling
// caller-side check before decoding stats
if _, ok := memo[batcher.BatchOperationStatsMemo]; !ok { // skip stats in the response } Type guard
func statsInMemo(memo map[string]*commonpb.Payload) bool {
_, ok := memo[batcher.BatchOperationStatsMemo]
return ok
} Try / catch
stats, err := wh.getCompletedBatchOperationStats(memo)
if err != nil { stats = batcher.BatchOperationStats{} /* respond without stats */ } Prevention
- Run a server version that writes batch stats into the workflow memo
- Don't overwrite batch workflow memo via UpdateWorkflow
- Handle legacy batch workflows gracefully in operational tooling
When it happens
Trigger: Calling ListBatchOperations/DescribeBatchOperation on a completed batch workflow whose memo lacks the 'batch-operation-stats' key - typically a batch workflow started by an older server version or one whose memo was overwritten.
Common situations: Clusters upgraded from versions before stats were stored in memo, batch workflows started with overridden/patched memo, or manual memo edits via UpdateWorkflow.
Related errors
- nexus operation processor failed
- cannot serialize HSM task. unable to cast to expected type
- completion token has no operation state machine reference
- namespace replication queue not enabled for cluster
- no nexus context set on context
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/d4ef3014a443b252.
Report an issue: GitHub.