t8y2/dbx · critical

Failed to create data dir

Error message

Failed to create data dir

What it means

After resolving the data directory, the app calls std::fs::create_dir_all(&data_dir) to ensure the directory exists, panicking with this message if the OS refuses. create_dir_all fails only on permission problems, path issues, or I/O errors (read-only filesystem, disk full), not because parents are missing.

Source

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

            let setup_start = Instant::now();
            eprintln!("[STARTUP] plugins registered in {:?}", startup_begin.elapsed());
            append_startup_probe(format!("setup entered after {:?}", startup_begin.elapsed()));

            if should_show_main_window_before_setup_tasks() {
                prepare_main_window_for_display(app.handle());
                show_main_window(app.handle());
                append_startup_probe(format!(
                    "early main window show requested; {}",
                    main_window_probe_state(app.handle())
                ));
            }

            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());

View on GitHub (pinned to c0390bff16)

Solutions

  1. Check whether a file occupies the data-dir path and remove/rename it so the directory can be created.
  2. Run the app under an account with write permission to the data directory, or configure a writable data dir via the app's data-dir mode/fallback.
  3. Free disk space or remount the volume read-write; surface the underlying io::Error instead of expect() to diagnose.

Example fix

// before
std::fs::create_dir_all(&data_dir).expect("Failed to create data dir");
// after
if let Err(e) = std::fs::create_dir_all(&data_dir) {
    eprintln!("[STARTUP] create_dir_all({data_dir:?}) failed: {e}");
    return Err(format!("data dir creation failed: {e}"));
}
Defensive patterns

Strategy: validation

Validate before calling

// Rust: preflight checks before create_dir_all
fn can_create_dir(path: &std::path::Path) -> Result<(), String> {
    if path.is_file() {
        return Err(format!("{} exists as a file", path.display()));
    }
    let parent = path.parent().unwrap_or(path);
    if !parent.exists() || std::fs::metadata(parent)?.permissions().readonly() {
        return Err(format!("parent {} not writable", parent.display()));
    }
    Ok(())
}

Try / catch

std::fs::create_dir_all(&data_dir)
    .map_err(|e| format!("create_dir_all({}): {e}", data_dir.display()))?;

Prevention

When it happens

Trigger: std::fs::create_dir_all(&data_dir) at lib.rs:1497 failing with PermissionDenied (no write access to the parent), AlreadyFile (a file exists at the data-dir path), or errors like ENOSPC/EROFS.

Common situations: A regular file already exists where the data dir should be (leftover corrupted install); running from a read-only mount or read-only home; enterprise-managed machines denying writes to the profile directory; full disk.

Related errors


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