hibiken/asynq · error

asynq

Error message

asynq: %v

What it means

UpdateTaskPayload rejects the queue name before touching Redis: base.ValidateQueueName returned an error, wrapped with 'asynq: %v'. Because %v is used (not %w), the validation error is not sentinel-wrappable; it is a plain formatted message. Queue names must be non-empty, alphanumeric-ish strings satisfying asynq's naming rules (no spaces or special characters).

Solutions

  1. Sanitize the queue name: letters/digits, no spaces or special characters, non-empty.
  2. Check argument order — first arg is queue name, second is task id.
  3. Reuse base.ValidateQueueName logic (or the asynq export) to validate the name before calling.
  4. Log the exact queue string to spot hidden whitespace or wrong interpolation.

Example fix

// before
err := insp.UpdateTaskPayload("email: high priority", taskID, newPayload)
// after
queue := "email-high-priority" // valid asynq queue name
if err := insp.UpdateTaskPayload(queue, taskID, newPayload); err != nil {
    log.Fatalf("update failed: %v", err)
}
Defensive patterns

Strategy: validation

Validate before calling

func validQueueName(q string) bool {
    return q != "" && !strings.ContainsAny(q, " :/\\")
}
// call only if validQueueName(queue)

Type guard

func sanitizeQueueName(q string) (string, bool) {
    q = strings.TrimSpace(q)
    if q == "" || !regexp.MustCompile(`^[a-zA-Z0-9_-]+$`).MatchString(q) {
        return "", false
    }
    return q, true
}

Prevention

When it happens

Trigger: Calling Inspector.UpdateTaskPayload(queue, id, payload) where queue contains invalid characters (spaces, ':', uppercase per validation rules) or is empty, producing an ErrQueueName validation error.

Common situations: Building queue names from user input or route parameters without sanitizing; accidentally passing an ID as the first argument; swapping the queue and task-id arguments.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at inspector.go:596

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

// UpdateTaskPayload updates a task with the given id from the given queue with given payload.
// The task needs to be in scheduled state,
// otherwise UpdateTaskPayload 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 not in scheduled state, it returns a non-nil error.
func (i *Inspector) UpdateTaskPayload(queue, id string, payload []byte) error {
	if err := base.ValidateQueueName(queue); err != nil {
		return fmt.Errorf("asynq: %v", err)
	}
	err := i.rdb.UpdateTaskPayload(queue, id, payload)
	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: %v", err)
	}
	return nil

}

// DeleteTask deletes a task with the given id from the given queue.
// The task needs to be in pending, scheduled, retry, or archived state,
// otherwise DeleteTask will return an error.
//

View on GitHub (pinned to d135f1439b)