temporalio/temporal · error

enqueue task request task is nil

Error message

enqueue task request task is nil

What it means

ErrEnqueueTaskRequestTaskIsNil (common/persistence/history_task_queue_manager.go:43) is returned by EnqueueTask when the request carries a nil Task pointer. The manager cannot serialize a nil task into a queue blob, so the enqueue is rejected up front as an invalid argument. It is a programmer-error guard preventing nil records from ever entering the task queue (which would later trip ErrHistoryTaskBlobIsNil on reads).

Solutions

  1. Ensure the Task field is populated before calling EnqueueTask
  2. Add an upstream nil check so nil tasks are rejected/logged at the producer
  3. Fix the task-construction code path that produced a nil task

Example fix

// before
mgr.EnqueueTask(ctx, &persistence.EnqueueTaskRequest{QueueType: category, ShardID: shardID}) // Task missing
// after
task := buildHistoryTask(...)
if task == nil {
    return errors.New("cannot enqueue nil history task")
}
mgr.EnqueueTask(ctx, &persistence.EnqueueTaskRequest{ShardID: shardID, Task: task})
Defensive patterns

Strategy: validation

Validate before calling

if req == nil || req.Task == nil {
    return errors.New("EnqueueTaskRequest.Task must be non-nil")
}
// safe to call EnqueueTask

Type guard

func taskIsEnqueueable(req *persistence.EnqueueTaskRequest) bool {
    return req != nil && req.Task != nil && req.ShardID > 0
}

Try / catch

err := mgr.EnqueueTask(ctx, req)
if err != nil {
    if strings.Contains(err.Error(), "enqueue task request task is nil") {
        logger.Error("nil task refused by queue manager", tag.Error(err))
        return err // programmer error: do not retry
    }
    return err
}

Prevention

When it happens

Trigger: Calling HistoryTaskQueueManagerImpl.EnqueueTask with &persistence.EnqueueTaskRequest{Task: nil} or a zero-value request struct.

Common situations: Constructing the request without populating Task; a nil task flowing from an upstream producer after a failed task build; test scaffolding forgetting to set the field.

Related errors


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

Appendix: source

Thrown at common/persistence/history_task_queue_manager.go:43

	// is returned when this whole top-level proto cannot be deserialized.
	//  Raw Task (a proto): <-- when this cannot be deserialized
	//	- ShardID
	//	- Blob (a serialized task)
	ErrMsgDeserializeRawHistoryTask = "failed to deserialize raw history task from task queue"
	// ErrMsgDeserializeHistoryTask is returned when the history task cannot be deserialized from the task queue. This
	// error is returned when the blob inside the raw task cannot be deserialized.
	//  Raw Task (a proto):
	//	- ShardID
	//	- Blob (a serialized task) <-- when this cannot be deserialized
	ErrMsgDeserializeHistoryTask = "failed to deserialize history task blob"
	// ErrMsgFailedToParseCategoryID is returned when category id cannot be parsed as an integer value.
	ErrMsgFailedToParseCategoryID = "failed to parse category id from queue name"
)

var (
	ErrReadTasksNonPositivePageSize = errors.New("page size to read history tasks must be positive")
	ErrHistoryTaskBlobIsNil         = errors.New("history task from queue has nil blob")
	ErrEnqueueTaskRequestTaskIsNil  = errors.New("enqueue task request task is nil")
	ErrQueueAlreadyExists           = errors.New("queue already exists")
	ErrShardIDInvalid               = errors.New("shard ID must be greater than 0")
	ErrInvalidQueueName             = errors.New("invalid queue name, expected 4 fields")
)

func NewHistoryTaskQueueManager(
	queue QueueV2,
	serializer serialization.Serializer,
) *HistoryTaskQueueManagerImpl {
	return &HistoryTaskQueueManagerImpl{
		queue:      queue,
		serializer: serializer,
	}
}

func (m *HistoryTaskQueueManagerImpl) EnqueueTask(
	ctx context.Context,
	request *EnqueueTaskRequest,

View on GitHub (pinned to bde624efd1)