hibiken/asynq · error

asynq: err

Error message

asynq: err

What it means

ArchiveTask returns fmt.Errorf("asynq: err") — an uninformative, non-wrapped literal — when base.ValidateQueueName rejects the queue name (empty or whitespace-only). Unlike sibling call sites, the underlying validation error is not embedded with %w, so the message gives no detail beyond 'asynq: err'.

Solutions

  1. Ensure the queue argument is a non-empty, trimmed string before calling ArchiveTask.
  2. Call base.ValidateQueueName(queue) yourself first to get the descriptive error message.
  3. Fix upstream config so a real queue name (e.g. "default") is always provided.

Example fix

// before
insp.ArchiveTask(cfg.Queue, id) // cfg.Queue may be ""
// after
if base.ValidateQueueName(cfg.Queue) != nil { cfg.Queue = "default" }
insp.ArchiveTask(cfg.Queue, id)
Defensive patterns

Strategy: validation

Validate before calling

if err := base.ValidateQueueName(queue); err != nil { return err } // yields the descriptive message

Type guard

func validQueue(q string) bool { return strings.TrimSpace(q) != "" }

Prevention

When it happens

Trigger: Inspector.ArchiveTask(queue, id) with queue == "" or " "; invalid queue name from config/env.

Common situations: Blank env var for queue name; template/config merge that dropped the queue key; passing an empty queue because a task-listing result was empty.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at inspector.go:747

// and reports the number of tasks archived.
func (i *Inspector) ArchiveAllAggregatingTasks(queue, group string) (int, error) {
	if err := base.ValidateQueueName(queue); err != nil {
		return 0, err
	}
	n, err := i.rdb.ArchiveAllAggregatingTasks(queue, group)
	return int(n), err
}

// ArchiveTask archives a task with the given id in the given queue.
// The task needs to be in pending, scheduled, or retry state, otherwise ArchiveTask
// will return an error.
//
// If a queue with the given name doesn't exist, it returns an error wrapping ErrQueueNotFound.
// If a task with the given id doesn't exist in the queue, it returns an error wrapping ErrTaskNotFound.
// If the task is in already archived, it returns a non-nil error.
func (i *Inspector) ArchiveTask(queue, id string) error {
	if err := base.ValidateQueueName(queue); err != nil {
		return fmt.Errorf("asynq: err")
	}
	err := i.rdb.ArchiveTask(queue, id)
	switch {
	case errors.IsQueueNotFound(err):
		return fmt.Errorf("asynq: %w", ErrQueueNotFound)
	case errors.IsTaskNotFound(err):
		return fmt.Errorf("asynq: %w", ErrTaskNotFound)
	case err != nil:
		return fmt.Errorf("asynq: %w", err)
	}
	return nil
}

// CancelProcessing sends a signal to cancel processing of the task
// given a task id. CancelProcessing is best-effort, which means that it does not
// guarantee that the task with the given id will be canceled. The return
// value only indicates whether the cancelation signal has been sent.
func (i *Inspector) CancelProcessing(id string) error {

View on GitHub (pinned to d135f1439b)