{"record":{"id":"0650f5996071afdc","repo":"tursodatabase/turso","slug":"invalid-mvcc-pull-revision-generation-revision","errorCode":null,"errorMessage":"invalid MVCC pull revision generation: {revision}","messagePattern":"invalid MVCC pull revision generation: (.+?)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"cli/sync_server.rs","lineNumber":925,"sourceCode":"            \"MVCC logical pull is not supported for in-memory sync server databases\"\n        ));\n    }\n    let path = if let Some(rest) = db_path.strip_prefix(\"file:\") {\n        rest.split_once('?').map_or(rest, |(path, _)| path)\n    } else {\n        db_path\n    };\n    Ok(PathBuf::from(path))\n}\n\nfn parse_mvcc_revision_offset(revision: &str, legacy_default: u64) -> Result<u64> {\n    if revision.is_empty() {\n        return Ok(0);\n    }\n    if let Some((generation, offset)) = revision.split_once(\":o\") {\n        let generation = generation\n            .strip_prefix('g')\n            .ok_or_else(|| anyhow!(\"invalid MVCC pull revision generation: {revision}\"))?\n            .parse::<u64>()\n            .map_err(|err| anyhow!(\"invalid MVCC pull revision generation: {revision}: {err}\"))?;\n        if generation != 1 {\n            return Err(anyhow!(\n                \"sync_server supports only single-generation MVCC logical pulls: {revision}\"\n            ));\n        }\n        return offset\n            .parse::<u64>()\n            .map_err(|err| anyhow!(\"invalid MVCC pull revision offset: {revision}: {err}\"));\n    }\n    // Older page bootstrap responses from this test server used WAL frame\n    // numbers. Treat them as \"the page snapshot already includes the current\n    // logical log\" so the required follow-up logical pull becomes a no-op.\n    Ok(legacy_default)\n}\n\nfn scan_mvcc_log(log: &[u8]) -> Result<MvccLogSnapshot> {","sourceCodeStart":907,"sourceCodeEnd":943,"githubUrl":"https://github.com/tursodatabase/turso/blob/bad083fafbefdeae9a42ec19bdaaad8918dcf411/cli/sync_server.rs#L907-L943","documentation":"client_revision strings containing \":o\" are parsed as g<generation>:o<offset>, and the generation segment must begin with a literal 'g'. Any other prefix — \"2:o5\", \"gen1:o5\", \"rev:o0\" — is rejected as an invalid generation with HTTP 500 before any log data is served.","triggerScenarios":"Hand-built or legacy revision strings sent to /pull-updates with stream_kind=MvccLogicalLog; clients composing the revision grammar themselves instead of reusing server-provided strings.","commonSituations":"Custom sync clients, ported scripts, and tests that fabricate revision strings; protocol drift where another component emits a different revision format.","solutions":["Only send revisions the server previously returned (the server_revision field of the last response).","Send an empty client_revision to pull from offset 0.","For page-bootstrapped clients, plain numeric WAL-frame revisions (no ':o') are accepted as the legacy default — use that form."],"exampleFix":"// before\nreq.client_revision = \"1:o128\".to_string();\n\n// after\nreq.client_revision = \"g1:o128\".to_string();","handlingStrategy":"validation","validationCode":"fn is_server_revision(rev: &str) -> bool {\n    if rev.is_empty() || rev.chars().all(|c| c.is_ascii_digit()) {\n        return true; // empty, or legacy WAL-frame revision\n    }\n    matches!(\n        rev.strip_prefix('g').and_then(|r| r.split_once(\":o\")),\n        Some((g, o)) if g.parse::<u64>().is_ok() && o.parse::<u64>().is_ok()\n    )\n}","typeGuard":null,"tryCatchPattern":"On 500 'invalid MVCC pull revision generation', do not retry the same string: re-read the last server_revision from the previous response, or send an empty client_revision to restart from offset 0.","preventionTips":["Only send revisions the server itself returned.","Validate the g<digits>:o<digits> grammar before sending custom values.","Keep legacy numeric revisions only for page-bootstrapped clients."],"tags":["mvcc","sync","revision","protocol","validation"],"backgroundTag":"invalid-revision-format","analyzedSha":"bad083fafbefdeae9a42ec19bdaaad8918dcf411","analyzedAt":"2026-08-16T23:12:11.798Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}