t8y2/dbx · critical

Failed to open storage

Error message

Failed to open storage

What it means

The app opens its SQLite-based Storage at <data_dir>/dbx.db with Storage::open(&db_path) and panics on failure. Opening fails when the file exists but is not a valid/corrupt database, the path is unwritable, or the database engine cannot initialize the file (locking, I/O errors).

Source

Thrown at src-tauri/src/lib.rs:1510

            append_startup_probe("resolving app data dir");
            let default_data_dir =
                app.path().app_data_dir().map_err(|e| e.to_string()).expect("Failed to resolve app data dir");
            let data_dir_resolution = data_dir::resolve_data_dir_with_mode(default_data_dir);
            let data_dir = data_dir_resolution.data_dir.clone();
            std::fs::create_dir_all(&data_dir).expect("Failed to create data dir");
            let data_dir_mode = startup_data_dir_mode(&data_dir_resolution.mode);
            append_startup_probe(format!("data dir ready mode={data_dir_mode}"));
            let alternative_data_dir = data_dir::alternative_data_dir(&data_dir_resolution);
            match maybe_import_user_data_db(&data_dir, alternative_data_dir.as_deref()) {
                Ok(result) => eprintln!("[STARTUP] data db fallback import: {result:?}"),
                Err(err) => eprintln!("[STARTUP] data db fallback import failed: {err}"),
            }
            let db_path = data_dir.join("dbx.db");

            let t = Instant::now();
            append_startup_probe(format!("opening storage file=dbx.db data_dir_mode={data_dir_mode}"));
            let storage = tauri::async_runtime::block_on(async {
                let s = Storage::open(&db_path).await.expect("Failed to open storage");
                eprintln!("[STARTUP]   Storage::open in {:?}", t.elapsed());
                append_startup_probe(format!("storage opened in {:?}", t.elapsed()));
                let t2 = Instant::now();
                s.migrate_from_json(&data_dir).await.expect("Failed to migrate JSON data");
                eprintln!("[STARTUP]   migrate_from_json in {:?}", t2.elapsed());
                append_startup_probe(format!("json migration completed in {:?}", t2.elapsed()));
                s
            });
            let desktop_settings = tauri::async_runtime::block_on(storage.load_desktop_settings()).unwrap_or_default();
            app.handle().plugin(
                tauri_plugin_log::Builder::default()
                    .timezone_strategy(tauri_plugin_log::TimezoneStrategy::UseLocal)
                    .format(|out, message, record| {
                        out.finish(format_args!(
                            "[{}][{}][{}] {}",
                            chrono::Local::now().format("%Y-%m-%d][%H:%M:%S%.3f"),
                            record.level(),
                            record.target(),

View on GitHub (pinned to c0390bff16)

Solutions

  1. Move the corrupt dbx.db (and -wal/-shm siblings) aside so a fresh database is created, after backing it up for recovery.
  2. Check for lockers (antivirus, sync clients like Dropbox/OneDrive, second app instance) and exclude the data dir from them.
  3. Verify write permissions and free space in the data dir; propagate the Storage::open error instead of expect() to enable fallback to the alternative data dir.

Example fix

// before
let s = Storage::open(&db_path).await.expect("Failed to open storage");
// after
let s = match Storage::open(&db_path).await {
    Ok(s) => s,
    Err(e) => {
        std::fs::rename(&db_path, db_path.with_extension("db.corrupt")).ok();
        Storage::open(&db_path).await.expect("Failed to open storage after reset")
    }
};
Defensive patterns

Strategy: fallback

Validate before calling

// Rust: probe the db file before opening
fn db_looks_recoverable(path: &std::path::Path) -> bool {
    match std::fs::read(path) {
        Ok(bytes) => bytes.starts_with(b"SQLite format 3\u{0}"),
        Err(_) => true, // missing file is fine: fresh open
    }
}

Try / catch

let storage = match Storage::open(&db_path).await {
    Ok(s) => s,
    Err(e) => {
        eprintln!("Storage::open failed: {e}; moving corrupt db aside");
        std::fs::rename(&db_path, db_path.with_extension("db.corrupt")).ok();
        Storage::open(&db_path).await?
    }
};

Prevention

When it happens

Trigger: Storage::open(&db_path).await at lib.rs:1510 erroring because dbx.db is corrupted or encrypted garbage, the data dir lacks write permission, another process holds an exclusive lock, or disk I/O fails during initialization.

Common situations: Crash or power loss left a truncated dbx.db; antivirus/backup tools locking the file; data dir restored from a partial backup; disk full while WAL/journal files are created.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/129450016593ab0d. Report an issue: GitHub.