hibiken/asynq · error

task cannot be nil

Error message

task cannot be nil

What it means

A generic validation guard in EnqueueContext: it fires when the caller passes a nil *Task pointer to enqueue, meaning there is no task payload or typename to serialize into redis, so enqueueing cannot proceed.

Solutions

  1. Pass a task created via asynq.NewTask(typename, payload) instead of nil
  2. Check for nil before calling Enqueue/EnqueueContext when the task comes from an optional or fallible code path
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at client.go:387 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of hibiken/asynq@d135f1439b (2026-09-07). Data as JSON: /api/errors/23c5cb76668de6dc. Report an issue: GitHub.

Appendix: source

Thrown at client.go:387

func (c *Client) Enqueue(task *Task, opts ...Option) (*TaskInfo, error) {
	return c.EnqueueContext(context.Background(), task, opts...)
}

// EnqueueContext enqueues the given task to a queue.
//
// EnqueueContext returns TaskInfo and nil error if the task is enqueued successfully, otherwise returns a non-nil error.
//
// The argument opts specifies the behavior of task processing.
// If there are conflicting Option values the last one overrides others.
// Any options provided to NewTask can be overridden by options passed to Enqueue.
// By default, max retry is set to 25 and timeout is set to 30 minutes.
//
// If no ProcessAt or ProcessIn options are provided, the task will be pending immediately.
//
// The first argument context applies to the enqueue operation. To specify task timeout and deadline, use Timeout and Deadline option instead.
func (c *Client) EnqueueContext(ctx context.Context, task *Task, opts ...Option) (*TaskInfo, error) {
	if task == nil {
		return nil, fmt.Errorf("task cannot be nil")
	}
	if strings.TrimSpace(task.Type()) == "" {
		return nil, fmt.Errorf("task typename cannot be empty")
	}
	// merge task options with the options provided at enqueue time.
	opts = append(task.opts, opts...)
	opt, err := composeOptions(opts...)
	if err != nil {
		return nil, err
	}
	deadline := noDeadline
	if !opt.deadline.IsZero() {
		deadline = opt.deadline
	}
	timeout := noTimeout
	if opt.timeout != 0 {
		timeout = opt.timeout
	}

View on GitHub (pinned to d135f1439b)