hibiken/asynq · error

task typename cannot be empty

Error message

task typename cannot be empty

What it means

Argument validation in EnqueueContext: the task's type name (its typename given to NewTask) is empty. The type name identifies which handler processes the task, so an empty name would produce an unprocessable task and is rejected at enqueue time.

Solutions

  1. Pass a non-empty typename to asynq.NewTask, e.g. asynq.NewTask("email:welcome", payload)
  2. Validate task.Type() before enqueueing when the task is built dynamically
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at client.go:390 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/4f90144d1048f14d. Report an issue: GitHub.

Appendix: source

Thrown at client.go:390

// 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
	}
	if deadline.Equal(noDeadline) && timeout == noTimeout {
		// If neither deadline nor timeout are set, use default timeout.
		timeout = defaultTimeout

View on GitHub (pinned to d135f1439b)