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
- 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.
- If the DB was never created, start the panel once so InitDB creates it, then dump.
- 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
- Derive srcPath from the panel's actual DB location instead of assuming /etc/x-ui/x-ui.db (Windows differs).
- Start the panel once before dumping so the DB file exists.
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
- sqlite backup destination already exists: %s
- destination already exists: %s
- open sqlite source: %w
- open sqlite destination: %w
- sqlite backup is unavailable for PostgreSQL
AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15).
Data as JSON: /api/errors/d2d98050a97f6c95.
Report an issue: GitHub.