navidrome/navidrome · error

creating taskqueue schema: %w

Error message

creating taskqueue schema: %w

What it means

This error wraps a failure from createTaskQueueSchema, which runs the CREATE TABLE statements for the task queue's queues/tasks tables on the plugin's SQLite database. If the schema cannot be created the database is closed and the service fails to start. Common causes are a corrupt or partially-written database file and SQLite I/O errors on disk.

Source

Thrown at plugins/host_taskqueue.go:103

// The given ctx bounds the service's background work (queue workers, cleanup loop).
func newTaskQueueService(ctx context.Context, pluginName string, manager *Manager, maxConcurrency int32) (*taskQueueServiceImpl, error) {
	dataDir := filepath.Join(conf.Server.DataFolder.String(), "plugins", pluginName)
	if err := os.MkdirAll(dataDir, 0700); err != nil {
		return nil, fmt.Errorf("creating plugin data directory: %w", err)
	}

	dbPath := filepath.Join(dataDir, "taskqueue.db")
	db, err := sql.Open("sqlite3", dbPath+"?_busy_timeout=5000&_journal_mode=WAL&_foreign_keys=off")
	if err != nil {
		return nil, fmt.Errorf("opening taskqueue database: %w", err)
	}

	db.SetMaxOpenConns(3)
	db.SetMaxIdleConns(1)

	if err := createTaskQueueSchema(db); err != nil {
		db.Close()
		return nil, fmt.Errorf("creating taskqueue schema: %w", err)
	}

	ctx, cancel := context.WithCancel(ctx) //nolint:gosec // cancel is stored in struct and called in Close()

	s := &taskQueueServiceImpl{
		pluginName:     pluginName,
		manager:        manager,
		maxConcurrency: maxConcurrency,
		db:             db,
		ctx:            ctx,
		cancel:         cancel,
		queues:         make(map[string]*queueState),
	}
	s.invokeCallbackFn = s.defaultInvokeCallback

	s.wg.Go(s.cleanupLoop)

	log.Debug("Initialized plugin taskqueue", "plugin", pluginName, "path", dbPath, "maxConcurrency", maxConcurrency)

View on GitHub (pinned to 4ed7494a32)

Solutions

  1. Read the wrapped error from createTaskQueueSchema to identify the SQLite error code (e.g. SQLITE_CORRUPT, SQLITE_BUSY, SQLITE_FULL)
  2. If the database is corrupt and its contents are disposable, stop the server and delete <dataFolder>/plugins/<pluginName>/taskqueue.db (plus -wal and -shm files) so it is recreated
  3. Free disk space or fix storage issues if the error indicates SQLITE_FULL or I/O errors
  4. Ensure no other process (backup tool, second server instance) has the database locked

Example fix

// before: corrupt db blocks startup
rm /var/lib/app/plugins/myplugin/taskqueue.db*
// after: server restarts and createTaskQueueSchema recreates a fresh schema
Defensive patterns

Strategy: fallback

Validate before calling

// check db file health before opening service
dbPath := filepath.Join(conf.Server.DataFolder.String(), "plugins", pluginName, "taskqueue.db")
probe, err := sql.Open("sqlite3", dbPath+"?_busy_timeout=5000")
if err == nil {
    if _, err := probe.Exec("PRAGMA integrity_check;"); err != nil {
        os.Remove(dbPath) // recreate corrupt disposable db
    }
    probe.Close()
}

Type guard

func isSqliteCorruptErr(err error) bool {
    return err != nil && strings.Contains(strings.ToLower(err.Error()), "corrupt")
}

Try / catch

s, err := newTaskQueueService(ctx, pluginName, mgr, maxConcurrency)
if err != nil && strings.Contains(err.Error(), "creating taskqueue schema") {
    if isSqliteCorruptErr(err) {
        os.Remove(filepath.Join(conf.Server.DataFolder.String(), "plugins", pluginName, "taskqueue.db"))
        s, err = newTaskQueueService(ctx, pluginName, mgr, maxConcurrency)
    }
}
return s, err

Prevention

When it happens

Trigger: createTaskQueueSchema returns an error when executing DDL against taskqueue.db — e.g. the SQLite file is corrupted, locked by another process, or the disk write fails.

Common situations: A previous crash left a corrupt taskqueue.db (WAL files out of sync); the data directory is on a full or failing disk; an external process holds a conflicting lock on the database file; SQLite version incompatibilities with an old database file.

Related errors


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