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
- Read the wrapped inner error to pinpoint the cause (I/O error, lock, schema, context).
- Confirm the data directory is accessible and not opened by another process.
- If the schema changed between versions, back up and remove/rename the old database file so it is recreated.
- 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
- Use long-enough context timeouts for polling loops
- Keep the DB file free of competing processes
- Recreate stale databases after plugin version upgrades
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
- creating queue: %w
- resetting stale tasks: %w
- enqueuing task: %w
- cancelling task: %w
- checking task existence: %w
AI-assisted analysis of navidrome/navidrome@4ed7494a32 (2026-09-01).
Data as JSON: /api/errors/57dcaf4437c333d9.
Report an issue: GitHub.