MHSanaei/3x-ui · error

database is not initialized

Error message

database is not initialized

What it means

BackupSQLite returns 'database is not initialized' when the package-level db handle is nil — i.e. BackupSQLite was called before database.InitDB succeeded (or after CloseDB). The function assumes the singleton GORM connection is live; without it there is no source database to copy from. This is an ordering bug in the caller, not a data problem.

Source

Thrown at internal/database/db.go:2185

	return errors.Is(err, gorm.ErrRecordNotFound)
}

func IsSQLiteDB(file io.ReaderAt) (bool, error) {
	signature := []byte("SQLite format 3\x00")
	buf := make([]byte, len(signature))
	_, err := file.ReadAt(buf, 0)
	if err != nil {
		return false, err
	}
	return bytes.Equal(buf, signature), nil
}

func BackupSQLite(dstPath string) (err error) {
	if IsPostgres() {
		return errors.New("sqlite backup is unavailable for PostgreSQL")
	}
	if db == nil {
		return errors.New("database is not initialized")
	}
	if _, err := os.Lstat(dstPath); err == nil {
		return fmt.Errorf("sqlite backup destination already exists: %s", dstPath)
	} else if !errors.Is(err, os.ErrNotExist) {
		return err
	}
	defer func() {
		if err != nil {
			_ = os.Remove(dstPath)
		}
	}()

	ctx, cancel := context.WithTimeout(context.Background(), backupSQLiteTimeout)
	defer cancel()

	sourceDB, err := db.DB()
	if err != nil {
		return err

View on GitHub (pinned to ad32144c42)

Solutions

  1. Call database.InitDB(...) (the app's normal boot sequence) before BackupSQLite
  2. In tests, follow the repo pattern: database.InitDB(filepath.Join(t.TempDir(), "x-ui.db")) with t.Cleanup(database.CloseDB)
  3. If this appears at runtime, check logs for an earlier InitDB failure that was swallowed
Defensive patterns

Strategy: validation

Validate before calling

if database.GetDB() == nil { // or expose an IsInitialized check
    return errors.New("init database before backup")
}

Try / catch

if err := database.BackupSQLite(dst); err != nil {
    if strings.Contains(err.Error(), "not initialized") {
        log.Fatal("InitDB must run before BackupSQLite — check boot order")
    }
    return err
}

Prevention

When it happens

Trigger: Calling BackupSQLite from a CLI subcommand path that skips InitDB; invoking it in a unit test without database.InitDB(t.TempDir()...); calling after CloseDB during shutdown.

Common situations: Custom tooling or tests that link the database package and call backup directly; startup races where a job fires before InitDB completes.

Related errors


AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15). Data as JSON: /api/errors/eaba4d366b800635. Report an issue: GitHub.