gitbutlerapp/gitbutler · error · anyhow::Error

Cannot import TOML into DB: TOML does not exist or is invali

Error message

Cannot import TOML into DB: TOML does not exist or is invalid

What it means

`import_toml_into_db` force-imports an externally restored legacy metadata TOML into the SQLite store (oplog restore and similar flows). It first classifies the file with `read_toml_info`; anything other than `TomlInfo::Parsed` — missing file, unreadable file, or TOML that fails to parse — aborts before the database is touched.

Source

Thrown at crates/but-meta/src/legacy/storage.rs:93

    }
    let mut snapshot = legacy_to_snapshot(vb, into_db_toml_file_info(db_state))?;
    let info = write_toml(path, vb)?;
    info.update_last_seen_metadata_on(&mut snapshot.state);
    persist_snapshot(&mut tx, snapshot)?;
    tx.commit()?;
    // The single choke point for metadata writes, so touching the sentinel here surfaces
    // out-of-process writes. Read-only syncs don't route through here.
    but_project_handle::write_refresh_sentinel(path);
    Ok(())
}

/// Import TOML into DB if TOML is valid, overwriting existing data forcefully.
///
/// This is meant for oplog restore and similar flows where TOML was restored externally.
pub fn import_toml_into_db(path: &Path) -> anyhow::Result<()> {
    let info = read_toml_info(path)?;
    let TomlInfo::Parsed(parsed) = info else {
        bail!("Cannot import TOML into DB: TOML does not exist or is invalid");
    };

    let mut db = db_handle_from_toml_path(path)?;
    let mut tx = db.immediate_transaction()?;
    let mut state = snapshot_state(path, &tx)?.unwrap_or_default().state;
    state.initialized = true;
    parsed.update_last_seen_metadata_on(&mut state);
    let snapshot = legacy_to_snapshot(&parsed.data, into_db_toml_file_info(state))?;
    persist_snapshot(&mut tx, snapshot)?;
    tx.commit()?;
    Ok(())
}

fn ensure_vb_storage_in_sync(
    path: &Path,
    tx: &mut but_db::Transaction<'_>,
) -> anyhow::Result<VirtualBranches> {
    let snapshot = snapshot_state(path, tx)?.unwrap_or_default();

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Verify the TOML file exists at the expected path and parses before importing
  2. Re-run the restore step that is supposed to produce the TOML, then retry the import
  3. If the file was hand-edited, fix the TOML syntax or restore the original backup

Example fix

// before
import_toml_into_db(&path)?;

// after: validate the payload parses as TOML first
let raw = std::fs::read_to_string(&path)?;
toml::from_str::<toml::Value>(&raw)?; // fails fast with a parse error
import_toml_into_db(&path)?;
Defensive patterns

Strategy: validation

Validate before calling

// Rust: verify the restored TOML exists and parses before import
let raw = std::fs::read_to_string(&path)
    .with_context(|| format!("metadata TOML missing at {}", path.display()))?;
toml::from_str::<toml::Value>(&raw)?; // fails fast with a parse error
import_toml_into_db(&path)?;

Try / catch

Catch the bail from import_toml_into_db and surface 'restore the metadata file first' — do not retry with the same broken payload.

Prevention

When it happens

Trigger: Calling `import_toml_into_db(path)` where the path does not point at a valid legacy metadata TOML file: file absent, empty, truncated, or syntactically invalid TOML.

Common situations: Oplog/backup restores where the TOML was never actually written back or landed at the wrong path; interrupted restores leaving truncated files; hand-edited metadata with syntax errors.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/2dfcf8c99c3af8e1. Report an issue: GitHub.