t8y2/dbx · error

Failed to migrate JSON data

Error message

Failed to migrate JSON data

What it means

After opening storage, dbx-web runs storage.migrate_from_json(&data_dir) to import legacy JSON data into the database and expects success. A failure here halts startup because partially migrated data would leave the app in an inconsistent state.

Source

Thrown at crates/dbx-web/src/main.rs:305

        .with_env_filter(
            tracing_subscriber::EnvFilter::try_from_default_env()
                .unwrap_or_else(|_| "dbx_web=info,tower_http=info".parse().unwrap()),
        )
        .init();

    rustls::crypto::aws_lc_rs::default_provider().install_default().expect("Failed to install rustls crypto provider");

    // Data directory
    let data_dir = std::env::var("DBX_DATA_DIR").map(std::path::PathBuf::from).unwrap_or_else(|_| {
        let home = std::env::var("HOME").unwrap_or_else(|_| ".".to_string());
        std::path::PathBuf::from(home).join(".dbx-web")
    });
    std::fs::create_dir_all(&data_dir).expect("Failed to create data directory");

    let app_state = {
        let db_path = data_dir.join("dbx.db");
        let storage = Storage::open(&db_path).await.expect("Failed to open storage");
        storage.migrate_from_json(&data_dir).await.expect("Failed to migrate JSON data");

        // Initialize core dialect registry and load external plugin dialects
        register_core_dialects();
        let registry = DialectRegistry::global();
        let plugin_dirs = vec![data_dir.join("plugins").join("dialects")];
        let load_result = DialectPluginLoader::scan_and_load(registry, &plugin_dirs);
        log::info!(
            "Dialect plugins loaded: {} success, {} errors, {} skipped",
            load_result.loaded.len(),
            load_result.errors.len(),
            load_result.skipped.len()
        );

        // Start dialect YAML hot-reload watcher
        let watch_dirs = plugin_dirs.clone();
        tokio::spawn(async move {
            if let Err(e) = DialectHotReload::run_forever(watch_dirs, DialectRegistry::global()).await {
                log::error!("Dialect hot-reload watcher exited: {e}");

View on GitHub (pinned to c0390bff16)

Solutions

  1. Validate/back up the legacy JSON files in the data directory, then fix or remove the malformed file causing the failure.
  2. Temporarily move the legacy JSON files out of data_dir to skip migration and start fresh (legacy data will not be imported).
  3. Restore the data directory from a backup and retry the upgrade.
  4. Check storage writability and disk space so migration writes can complete.
  5. Change the code to log the detailed migration error rather than a bare expect panic.

Example fix

// before
storage.migrate_from_json(&data_dir).await.expect("Failed to migrate JSON data");
// after
storage.migrate_from_json(&data_dir).await
    .unwrap_or_else(|e| panic!("Failed to migrate JSON data from {}: {e}", data_dir.display()));
Defensive patterns

Strategy: validation

Validate before calling

fn legacy_json_files_parse(data_dir: &std::path::Path) -> bool {
    std::fs::read_dir(data_dir)
        .map(|entries| entries.flatten()
            .filter(|e| e.path().extension().map(|x| x == "json").unwrap_or(false))
            .all(|e| std::fs::read_to_string(e.path()).map(|s| serde_json::from_str::<serde_json::Value>(&s).is_ok()).unwrap_or(false)))
        .unwrap_or(false)
}

Try / catch

if let Err(e) = storage.migrate_from_json(&data_dir).await {
    eprintln!("Failed to migrate JSON data from {}: {e}", data_dir.display());
    std::process::exit(1);
}

Prevention

When it happens

Trigger: migrate_from_json fails when legacy JSON files in the data directory are malformed, unreadable, or fail schema parsing; the migration writes fail due to storage errors; or a previous migration left partial/corrupt state.

Common situations: Upgrading from an older file-based dbx-web version with hand-edited or truncated JSON files; JSON encoding issues after locale/manual edits; read-only mounts making legacy files unreadable or migration writes impossible.

Related errors


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