IceWhaleTech/CasaOS · critical

sqlite connect error

Error message

sqlite connect error

What it means

A panic raised by GetDb() in pkg/sqlite/db.go when gorm.Open(sqlite.Open(...)) fails to open the SQLite database file at dbPath/casaOS.db. Unlike the HTTP errors, this is a process-killing panic, not a returned error: any caller that triggers the first initialization on a bad path crashes the whole CasaOS binary. Typical root causes are an unwritable/missing directory, a corrupted database file, or file locking conflicts from concurrent access (SQLite allows one writer).

Source

Thrown at pkg/sqlite/db.go:35

	"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
	model2 "github.com/IceWhaleTech/CasaOS/service/model"
	"github.com/glebarez/sqlite"
	"gorm.io/gorm"
)

var gdb *gorm.DB

func GetDb(dbPath string) *gorm.DB {
	if gdb != nil {
		return gdb
	}
	// Refer https://github.com/go-sql-driver/mysql#dsn-data-source-name
	// dsn := fmt.Sprintf("%v:%v@tcp(%v:%v)/%v?charset=utf8mb4&parseTime=True&loc=Local", m.User, m.PWD, m.IP, m.Port, m.DBName)
	// db, err := gorm.Open(mysql2.Open(dsn), &gorm.Config{})
	file.IsNotExistMkDir(dbPath)
	db, err := gorm.Open(sqlite.Open(dbPath+"/casaOS.db"), &gorm.Config{})
	if err != nil {
		panic("sqlite connect error")
	}

	c, _ := db.DB()
	c.SetMaxIdleConns(10)
	c.SetMaxOpenConns(1)
	c.SetConnMaxIdleTime(time.Second * 1000)
	gdb = db

	err = db.AutoMigrate(&model2.AppNotify{}, model2.SharesDBModel{}, model2.ConnectionsDBModel{}, model2.PeerDriveDBModel{})
	if err != nil {
		fmt.Println(err)
	}

	db.Exec("DROP TABLE IF EXISTS o_application")
	db.Exec("DROP TABLE IF EXISTS o_friend")
	db.Exec("DROP TABLE IF EXISTS o_person_download")
	db.Exec("DROP TABLE IF EXISTS o_person_down_record")
	return db

View on GitHub (pinned to 0d3b2f444e)

Solutions

  1. Check permissions/ownership of dbPath (ls -ld) and chown it to the user running CasaOS; ensure it is writable.
  2. Check disk space (df -h) and free space so SQLite can write its journal/WAL.
  3. If another instance holds the file, stop it (only one CasaOS may own casaOS.db), or move the stale lock aside.
  4. If the db is corrupt, back it up and delete casaOS.db so AutoMigrate rebuilds a fresh schema (accepting loss of notify/shares/connections tables).
  5. Longer term, replace panic with a returned error or a logged fatal that includes the gorm err so the cause is visible.

Example fix

// before
db, err := gorm.Open(sqlite.Open(dbPath+"/casaOS.db"), &gorm.Config{})
if err != nil {
    panic("sqlite connect error")
}

// after
db, err := gorm.Open(sqlite.Open(dbPath+"/casaOS.db"), &gorm.Config{})
if err != nil {
    logger.Error("sqlite connect error", zap.String("path", dbPath), zap.Error(err))
    panic(fmt.Sprintf("sqlite connect error: %v", err))
}
Defensive patterns

Strategy: validation

Validate before calling

// before first GetDb() call
info, err := os.Stat(dbPath)
if err != nil || !info.IsDir() {
    return fmt.Errorf("db path %s missing or not a directory", dbPath)
}
if err := unix.Access(dbPath, unix.W_OK); err != nil {
    return fmt.Errorf("db path %s not writable", dbPath)
}
disk := syscall.Statfs_t{}
if err := syscall.Statfs(dbPath, &disk); err == nil && disk.Bavail*uint64(disk.Bsize) < 10<<20 {
    return fmt.Errorf("less than 10MB free for sqlite db")
}

Try / catch

// GetDb panics, so guard at process level if you embed CasaOS code:
func safeDbInit(path string) (db *gorm.DB, err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("sqlite init panic: %v", r)
        }
    }()
    return sqlite.GetDb(path), nil
}

Prevention

When it happens

Trigger: (1) dbPath directory has wrong ownership/permissions (common when the data dir was moved or restored), (2) casaOS.db is corrupt from an unclean power-off (no WAL checkpoint completed), (3) another CasaOS instance or process holds the file lock, (4) disk full so SQLite cannot create its journal, (5) dbPath on a filesystem (some NFS/FUSE mounts) without working POSIX locks.

Common situations: First start after OS reinstall with an old /DATA partition preserved; SD-card wear causing a truncated db file; running two CasaOS versions simultaneously during an upgrade; Docker bind-mount with read-only volume for /var/lib/casaos; migration tool copying the db with wrong uid.

Related errors


AI-assisted analysis of IceWhaleTech/CasaOS@0d3b2f444e (2026-08-15). Data as JSON: /api/errors/ca0cad6e7e889637. Report an issue: GitHub.