{"record":{"id":"194131be72330016","repo":"GitoxideLabs/gitoxide","slug":"cannot-handle-database-with-version-version-can","errorCode":null,"errorMessage":"Cannot handle database with version {version}, cannot yet migrate to {VERSION} - maybe migrate by hand?","messagePattern":"Cannot handle database with version (.+?), cannot yet migrate to (.+?) - maybe migrate by hand\\?","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gitoxide-core/src/corpus/db.rs","lineNumber":68,"sourceCode":"/// A version to be incremented whenever the database layout is changed, to refresh it automatically.\nconst VERSION: usize = 1;\n\npub fn create(path: impl AsRef<std::path::Path>) -> anyhow::Result<rusqlite::Connection> {\n    let path = path.as_ref();\n    let con = rusqlite::Connection::open(path)?;\n    let meta_table = r#\"\n    CREATE TABLE if not exists meta(\n        version int\n    )\"#;\n    con.execute_batch(meta_table)?;\n    let version: Option<usize> = con.query_row(\"SELECT version FROM meta\", [], |r| r.get(0)).optional()?;\n    match version {\n        None => {\n            con.execute(\"INSERT into meta(version) values(?)\", params![VERSION])?;\n        }\n        Some(version) if version != VERSION => match con.close() {\n            Ok(()) => {\n                bail!(\n                    \"Cannot handle database with version {version}, cannot yet migrate to {VERSION} - maybe migrate by hand?\"\n                );\n            }\n            Err((_, err)) => return Err(err.into()),\n        },\n        _ => {}\n    }\n    con.execute_batch(\"PRAGMA synchronous = OFF; PRAGMA journal_mode = WAL; PRAGMA wal_checkpoint(FULL); \")?;\n    con.execute_batch(\n        r#\"\n    CREATE TABLE if not exists runner(\n        id integer PRIMARY KEY,\n        vendor text,\n        brand text,\n        host_name text, -- this is just to help ID the runner\n        UNIQUE (vendor, brand)\n    )\n    \"#,","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gitoxide-core/src/corpus/db.rs#L50-L86","documentation":"When `gitoxide_core::corpus::db::create` opens a corpus database whose `meta.version` exists and differs from the supported `VERSION`, it closes the connection and aborts with this bail! message. The corpus schema has no migration machinery, so mismatched versions are refused rather than migrated, and the user is told to migrate manually.","triggerScenarios":"Opening/creating a corpus database file created by a different gitoxide-core version whose stored schema version does not match the compiled-in `VERSION` constant.","commonSituations":"Upgrading or downgrading gitoxide and reusing an old corpus database from a benchmark/revision-collection run.","solutions":["Delete or archive the old corpus database and let `create` build a fresh one with the current version.","Migrate the database by hand (adjust the `meta.version` row and schema) to match the expected VERSION.","Pin the gitoxide version that matches the existing database.","Inspect the current version with a SQL query: `SELECT version FROM meta;` and compare with the expected constant."],"exampleFix":"// before\nmatch version {\n    Some(version) if version != VERSION => match con.close() {\n        Ok(()) => bail!(\"Cannot handle database with version {version}, cannot yet migrate to {VERSION} - maybe migrate by hand?\"),\n        Err((_, err)) => return Err(err.into()),\n    },\n    _ => {}\n}\n// after\nmatch version {\n    None => { con.execute(\"INSERT into meta(version) values(?)\", params![VERSION])?; }\n    Some(v) if v != VERSION => { migrations::apply(&mut con, v, VERSION)?; }\n    _ => {}\n}","handlingStrategy":"try-catch","validationCode":"// Check the corpus DB version before opening with the new tool\nlet version: Option<u32> = rusqlite::Connection::open(db_path)?\n    .query_row(\"SELECT version FROM meta\", [], |r| r.get(0))\n    .ok();\nif let Some(v) = version {\n    if v != EXPECTED_VERSION { eprintln!(\"corpus DB version {v} unsupported - migrate or recreate\"); }\n}","typeGuard":null,"tryCatchPattern":"match gitoxide_core::corpus::db::create(&db_path) {\n    Ok(db) => { /* proceed */ }\n    Err(err) if err.to_string().contains(\"cannot yet migrate\") => {\n        // archive old DB and recreate\n        std::fs::rename(db_path, db_path.with_extension(\"old\"))?;\n        let db = gitoxide_core::corpus::db::create(&db_path)?;\n    }\n    Err(err) => return Err(err.into()),\n}","preventionTips":["Check the `meta.version` row before reusing an existing corpus DB with a new gitoxide build.","Treat corpus databases as version-specific artifacts; recreate them after upgrading gitoxide.","Record the gitoxide version alongside benchmark/corpus artifacts so mismatches are obvious.","If you must keep data, export it before migrating, since the tool migrates nothing automatically."],"tags":["sqlite","database","version-mismatch","migration","gitoxide-core"],"backgroundTag":"incompatible-source-type","analyzedSha":"e73179060badf27222d790981fac3f84c1830a7e","analyzedAt":"2026-09-08T11:26:50.865Z","contentChangedAt":"2026-09-08T11:26:50.865Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}