JuliusBrussee/caveman · error
configure sqlite journal
Error message
configure sqlite journal: %w
What it means
This error wraps a failure to persist the WAL journal mode on the opened SQLite database (persistSQLiteWAL). The store requires WAL for concurrent readers, and if the journal mode cannot be applied/persisted the open is aborted and the half-opened db is closed. This typically means the underlying Exec setting PRAGMA journal_mode=WAL failed.
Solutions
- Check no other process holds a write lock on the database; increase busy_timeout if contention is heavy
- Move the database to a local filesystem that supports WAL and -shm sidecar files
- Run the PRAGMA journal_mode=WAL manually with the sqlite3 CLI to see the underlying failure
- If WAL is impossible in your environment, configure a non-WAL journal mode explicitly if the library supports it
Example fix
// before
rows, err := db.Query("SELECT data FROM ccr") // on NFS, WAL pragma failed at open
// after
// relocate db to local disk:
store, err := ccr.Open("/var/lib/app/ccr.db") // local ext4/apfs volume Defensive patterns
Strategy: retry
Validate before calling
// verify WAL is supportable before opening
out, err := exec.Command("sqlite3", dbPath, "PRAGMA journal_mode;").Output()
if err != nil {
return fmt.Errorf("db %s not inspectable: %w", dbPath, err)
} Try / catch
store, err := ccr.Open(dbPath)
if err != nil && strings.Contains(err.Error(), "configure sqlite journal") {
// fall back to local disk or retry after lock clears
time.Sleep(250 * time.Millisecond)
store, err = ccr.Open(dbPath)
} Prevention
- Keep the database on a local filesystem, not NFS/SMB/cloud-sync folders
- Avoid multiple long-running writers in separate processes
- Pre-check journal mode with the sqlite3 CLI on exotic mounts
When it happens
Trigger: persistSQLiteWAL's PRAGMA journal_mode=WAL statement returns an error, e.g. the database is locked by another process beyond busy_timeout, or the file is on a filesystem that rejects the operation.
Common situations: Databases on network mounts (NFS/SMB) where WAL cannot be established; a long-running writer in another process holding the lock; read-only file media.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- prefix replacement: entry unreadable after write
- read sqlite journal mode
- secure sqlite sidecar
- : : inspect database
- broken supersession history at
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/6e353fd4b3c45924.
Report an issue: GitHub.
Appendix: source
Thrown at engine/ccr/store_sqlite.go:203
// PrepareSQLitePathCanonical already created the file. Never recreate
// it if it vanishes between preparation and the driver's open.
dsn += "&mode=rw"
}
db, err := sql.Open("sqlite", dsn)
if err != nil {
return nil, fmt.Errorf("open sqlite %q: %w", canonicalPath, err)
}
// One writer connection. With a single connection every statement serializes
// in-process (no self-contention) while busy_timeout absorbs cross-process
// contention; it is also mandatory for an in-memory DSN, where a second
// pooled connection would be a second, empty database.
db.SetMaxOpenConns(1)
db.SetMaxIdleConns(1)
walJournal := false
if canonicalPath != ":memory:" {
if err := persistSQLiteWAL(db); err != nil {
closeSQLiteAfterOpenFailure(db, canonicalPath)
return nil, fmt.Errorf("configure sqlite journal: %w", err)
}
// A filesystem that cannot back -shm (NFS, SMB, some roaming profiles)
// leaves the DSN's journal_mode request unapplied. Requiring the WAL
// sidecars there would report a perfectly good database as replaced.
mode, err := sqliteJournalMode(db)
if err != nil {
closeSQLiteAfterOpenFailure(db, canonicalPath)
return nil, fmt.Errorf("read sqlite journal mode: %w", err)
}
walJournal = strings.EqualFold(mode, "wal")
}
if err := RetryOnBusy(func() error { _, e := db.Exec(schema); return e }); err != nil {
closeSQLiteAfterOpenFailure(db, canonicalPath)
return nil, fmt.Errorf("migrate sqlite %q: %w", canonicalPath, err)
}
if err := RetryOnBusy(func() error { return ensureMetadataColumn(db) }); err != nil {
closeSQLiteAfterOpenFailure(db, canonicalPath)
return nil, fmt.Errorf("migrate sqlite metadata %q: %w", canonicalPath, err)View on GitHub (pinned to 3ee70a1026)