hibiken/asynq · error

queue is not empty

Error message

queue is not empty

What it means

Sentinel error ErrQueueNotEmpty, returned by Inspector.DeleteQueue when the target queue still holds pending/active/scheduled tasks. It fires because DeleteQueue refuses to delete a non-empty queue unless called with force=true; callers detect it via errors.Is and can either purge tasks first or retry with force.

Solutions

  1. Drain or requeue the tasks first (use Inspector to list and delete/archive them).
  2. Call DeleteQueue with force=true after confirming no tasks are active.
  3. Pause the queue and wait for active tasks to complete, then delete.
  4. Treat errors.Is(err, asynq.ErrQueueNotEmpty) as 'retry after drain'.

Example fix

// before
insp.DeleteQueue("legacy", false)
// after
if err := insp.DeleteQueue("legacy", true); err != nil {
    log.Printf("queue still draining: %v", err)
}
Defensive patterns

Strategy: type-guard

Validate before calling

stats, err := insp.Stats(qname)
if err == nil && stats.Pending+stats.Scheduled+stats.Archived > 0 { return ErrQueueStillHasTasks }

Type guard

func isQueueNotEmpty(err error) bool { return errors.Is(err, asynq.ErrQueueNotEmpty) }

Try / catch

if err := insp.DeleteQueue(q, true); err != nil {
    if isQueueNotEmpty(err) { return ErrRetryAfterDrain }
    return err
}

Prevention

When it happens

Trigger: inspector.DeleteQueue(q, false) on a queue with pending/scheduled/archived tasks; DeleteQueue(q, true) while tasks are actively being processed.

Common situations: Decommissioning a queue that still has backlog; trying to force-delete during live traffic; forgetting force only bypasses size limits, not active tasks.

Related errors


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

Appendix: source

Thrown at inspector.go:210

	}
	var res []*DailyStats
	for _, s := range stats {
		res = append(res, &DailyStats{
			Queue:     s.Queue,
			Processed: s.Processed,
			Failed:    s.Failed,
			Date:      s.Time,
		})
	}
	return res, nil
}

var (
	// ErrQueueNotFound indicates that the specified queue does not exist.
	ErrQueueNotFound = errors.New("queue not found")

	// ErrQueueNotEmpty indicates that the specified queue is not empty.
	ErrQueueNotEmpty = errors.New("queue is not empty")

	// ErrTaskNotFound indicates that the specified task cannot be found in the queue.
	ErrTaskNotFound = errors.New("task not found")
)

// DeleteQueue removes the specified queue.
//
// If force is set to true, DeleteQueue will remove the queue regardless of
// the queue size as long as no tasks are active in the queue.
// If force is set to false, DeleteQueue will remove the queue only if
// the queue is empty.
//
// If the specified queue does not exist, DeleteQueue returns ErrQueueNotFound.
// If force is set to false and the specified queue is not empty, DeleteQueue
// returns ErrQueueNotEmpty.
func (i *Inspector) DeleteQueue(queue string, force bool) error {
	err := i.rdb.RemoveQueue(queue, force)
	if errors.IsQueueNotFound(err) {

View on GitHub (pinned to d135f1439b)