{"record":{"id":"94b855b13564d12f","repo":"t8y2/dbx","slug":"failed-to-open-storage","errorCode":null,"errorMessage":"Failed to open storage","messagePattern":"Failed to open storage","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/dbx-web/src/main.rs","lineNumber":304,"sourceCode":"    tracing_subscriber::fmt()\n        .with_env_filter(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| \"dbx_web=info,tower_http=info\".parse().unwrap()),\n        )\n        .init();\n\n    rustls::crypto::aws_lc_rs::default_provider().install_default().expect(\"Failed to install rustls crypto provider\");\n\n    // Data directory\n    let data_dir = std::env::var(\"DBX_DATA_DIR\").map(std::path::PathBuf::from).unwrap_or_else(|_| {\n        let home = std::env::var(\"HOME\").unwrap_or_else(|_| \".\".to_string());\n        std::path::PathBuf::from(home).join(\".dbx-web\")\n    });\n    std::fs::create_dir_all(&data_dir).expect(\"Failed to create data directory\");\n\n    let app_state = {\n        let db_path = data_dir.join(\"dbx.db\");\n        let storage = Storage::open(&db_path).await.expect(\"Failed to open storage\");\n        storage.migrate_from_json(&data_dir).await.expect(\"Failed to migrate JSON data\");\n\n        // Initialize core dialect registry and load external plugin dialects\n        register_core_dialects();\n        let registry = DialectRegistry::global();\n        let plugin_dirs = vec![data_dir.join(\"plugins\").join(\"dialects\")];\n        let load_result = DialectPluginLoader::scan_and_load(registry, &plugin_dirs);\n        log::info!(\n            \"Dialect plugins loaded: {} success, {} errors, {} skipped\",\n            load_result.loaded.len(),\n            load_result.errors.len(),\n            load_result.skipped.len()\n        );\n\n        // Start dialect YAML hot-reload watcher\n        let watch_dirs = plugin_dirs.clone();\n        tokio::spawn(async move {\n            if let Err(e) = DialectHotReload::run_forever(watch_dirs, DialectRegistry::global()).await {","sourceCodeStart":286,"sourceCodeEnd":322,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/crates/dbx-web/src/main.rs#L286-L322","documentation":"Panics/aborts in dbx-web main during startup when opening the application storage (database under DBX_DATA_DIR) fails — the storage layer could not be initialized (unwritable data directory, locked database file, or corrupted store). The web server refuses to start without working persistence.","triggerScenarios":"Storage::open(&db_path) fails when the data directory is unwritable, the SQLite file is corrupted or locked, disk is full, or the db file format is incompatible with the current rusqlite/sqlx version.","commonSituations":"Corrupted dbx.db after a crash or disk-full event; another dbx-web instance holding the SQLite lock; wrong ownership on a mounted volume; upgrading across an incompatible database schema version.","solutions":["Check that no other dbx-web process is using dbx.db and that the file/directory is writable.","Verify disk space and inode availability on the data volume.","If the database is corrupted, restore from backup or move dbx.db aside to re-initialize (losing local data).","Run migrations/schema fixes from the same or newer dbx version; avoid downgrading across schema changes.","Wrap Storage::open in error handling that logs the underlying SQLite error instead of a bare panic."],"exampleFix":"// before\nlet storage = Storage::open(&db_path).await.expect(\"Failed to open storage\");\n// after\nlet storage = Storage::open(&db_path)\n    .await\n    .unwrap_or_else(|e| panic!(\"Failed to open storage at {}: {e}\", db_path.display()));","handlingStrategy":"try-catch","validationCode":"let db_path = data_dir.join(\"dbx.db\");\nlet db_ok = std::path::Path::new(&db_path).map(|p| !p.exists() || p.metadata().map(|m| m.is_file()).unwrap_or(false)).unwrap_or(false)\n    && data_dir_writable(&data_dir);","typeGuard":null,"tryCatchPattern":"let storage = match Storage::open(&db_path).await {\n    Ok(s) => s,\n    Err(e) => { eprintln!(\"Failed to open storage {}: {e}\", db_path.display()); std::process::exit(1); }\n};","preventionTips":["Ensure only one dbx-web instance accesses dbx.db at a time.","Back up dbx.db before upgrades and monitor disk space.","Avoid downgrading across incompatible schema versions.","Check file permissions/ownership on mounted volumes."],"tags":["sqlite","rust","storage","startup"],"backgroundTag":"database-open-failed","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}