navidrome/navidrome · error

getting task info: %w

Error message

getting task info: %w

What it means

Get wraps any non-ErrNoRows error from the tasks-table SELECT with 'getting task info: %w'. Unlike the not-found case, this signals a database-level failure while reading status, message, and attempt for the given task ID.

Source

Thrown at plugins/host_taskqueue.go:303

	if err != nil {
		return "", fmt.Errorf("enqueuing task: %w", err)
	}

	qs.notifyWorkers()
	log.Trace(ctx, "Enqueued task", "plugin", s.pluginName, "queue", queueName, "taskID", taskID)
	return taskID, nil
}

// Get returns the current state of a task.
func (s *taskQueueServiceImpl) Get(ctx context.Context, taskID string) (*host.TaskInfo, error) {
	var info host.TaskInfo
	err := s.db.QueryRowContext(ctx, `SELECT status, message, attempt FROM tasks WHERE id = ?`, taskID).
		Scan(&info.Status, &info.Message, &info.Attempt)
	if errors.Is(err, sql.ErrNoRows) {
		return nil, fmt.Errorf("task %q not found", taskID)
	}
	if err != nil {
		return nil, fmt.Errorf("getting task info: %w", err)
	}
	return &info, nil
}

// Cancel cancels a pending task.
func (s *taskQueueServiceImpl) Cancel(ctx context.Context, taskID string) error {
	now := time.Now().UnixMilli()
	result, err := s.db.ExecContext(ctx, `
		UPDATE tasks SET status = ?, updated_at = ? WHERE id = ? AND status = ?
	`, taskStatusCancelled, now, taskID, taskStatusPending)
	if err != nil {
		return fmt.Errorf("cancelling task: %w", err)
	}

	rowsAffected, err := result.RowsAffected()
	if err != nil {
		return fmt.Errorf("checking cancel result: %w", err)
	}

View on GitHub (pinned to 4ed7494a32)

Solutions

  1. Read the wrapped inner error to pinpoint the cause (I/O error, lock, schema, context).
  2. Confirm the data directory is accessible and not opened by another process.
  3. If the schema changed between versions, back up and remove/rename the old database file so it is recreated.
  4. Retry with a fresh or longer-lived context if the error is context cancellation or a transient lock.
Defensive patterns

Strategy: try-catch

Try / catch

info, err := q.Get(ctx, taskID)
if err != nil {
    if errors.Is(err, context.Canceled) || ctx.Err() != nil {
        return retryGet(taskID)
    }
    if strings.Contains(err.Error(), "not found") {
        return nil // not-found is a separate, expected path
    }
    return fmt.Errorf("DB read failed: %w", err)
}

Prevention

When it happens

Trigger: QueryRowContext fails for reasons other than no rows: the SQLite database is locked/corrupt, the context was cancelled mid-query, the tasks table schema is incompatible (missing columns after a version change), or the DB file is unreadable.

Common situations: A second process holding a write lock on the DB; corrupt database from a hard crash; querying a data directory created by an older plugin version whose tasks table lacks new columns; caller cancelling the context during polling loops.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


AI-assisted analysis of navidrome/navidrome@4ed7494a32 (2026-09-01). Data as JSON: /api/errors/57dcaf4437c333d9. Report an issue: GitHub.