MHSanaei/3x-ui · error

source sqlite not found at %s: %w

Error message

source sqlite not found at %s: %w

What it means

DumpSQLiteToBytes stats srcPath first and wraps the failure — the SQLite file to dump does not exist (or is unreadable at the OS level). Everything downstream (gorm open, .dump-style SQL generation) is skipped. Usually a wrong path or a database that was never initialized on this host.

Source

Thrown at internal/database/dump_sqlite.go:34

// DumpSQLite writes a portable SQL text dump of the SQLite database at srcPath
// to outPath. The output mirrors the `sqlite3 .dump` format (schema + data +
// indexes wrapped in a transaction), so it can be rebuilt with RestoreSQLite or
// loaded by the sqlite3 CLI. The source database is opened read-only in effect
// and left untouched.
func DumpSQLite(srcPath, outPath string) error {
	data, err := DumpSQLiteToBytes(srcPath)
	if err != nil {
		return err
	}
	return os.WriteFile(outPath, data, 0o644)
}

// DumpSQLiteToBytes builds the same `sqlite3 .dump`-style SQL text as DumpSQLite
// but returns it in memory, which the panel uses to stream a migration download.
func DumpSQLiteToBytes(srcPath string) ([]byte, error) {
	if _, err := os.Stat(srcPath); err != nil {
		return nil, fmt.Errorf("source sqlite not found at %s: %w", srcPath, err)
	}

	gdb, err := gorm.Open(sqlite.Open(srcPath), &gorm.Config{Logger: logger.Discard})
	if err != nil {
		return nil, err
	}
	sqlDB, err := gdb.DB()
	if err != nil {
		return nil, err
	}
	defer sqlDB.Close()

	var b strings.Builder
	b.WriteString("PRAGMA foreign_keys=OFF;\n")
	b.WriteString("BEGIN TRANSACTION;\n")

	// Tables in creation order, each followed by its data.
	type object struct{ name, ddl string }

View on GitHub (pinned to ad32144c42)

Solutions

  1. Confirm the actual DB path (default /etc/x-ui/x-ui.db on Linux; executable dir on Windows) — check the running panel's config/logs.
  2. If the DB was never created, start the panel once so InitDB creates it, then dump.
  3. Check for mount/permission issues making an existing file invisible to the process (os.Stat error text will say which).
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.Stat(srcPath); err != nil {
    return fmt.Errorf("sqlite source missing: %w", err)
}

Prevention

When it happens

Trigger: Calling DumpSQLite with a path other than the real DB location (e.g. /etc/x-ui/x-ui.db when the panel runs from a different dir or Windows layout); running the dump before first panel start created the DB; a typo'd path argument.

Common situations: Manual migration prep where the operator guesses the DB path; Docker setups where the volume is mounted elsewhere; fresh installs invoking dump tooling immediately.

Related errors


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