{"record":{"id":"2c453935872d972f","repo":"zeroclaw-labs/zeroclaw","slug":"target-v-target-exceeds-current-schema-version-v","errorCode":null,"errorMessage":"target V{target} exceeds CURRENT_SCHEMA_VERSION (V{CURRENT_SCHEMA_VERSION})","messagePattern":"target V(.+?) exceeds CURRENT_SCHEMA_VERSION \\(V(.+?)\\)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-config/src/migration.rs","lineNumber":829,"sourceCode":"\nconst _: () = assert!(\n    MIGRATION_STEPS.len() as u32 == CURRENT_SCHEMA_VERSION,\n    \"MIGRATION_STEPS must have exactly one entry per schema version \\\n     (length = CURRENT_SCHEMA_VERSION, including the slot-0 padding)\",\n);\n\n/// Run the typed migration chain from `from` up to `CURRENT_SCHEMA_VERSION`.\n/// `from` must be `< CURRENT_SCHEMA_VERSION` (caller checks).\nfn run_chain(value: toml::Value, from: u32) -> Result<toml::Value> {\n    run_chain_until(value, from, CURRENT_SCHEMA_VERSION)\n}\n\nfn run_chain_until(value: toml::Value, from: u32, target: u32) -> Result<toml::Value> {\n    if target < from {\n        anyhow::bail!(\"cannot migrate backwards from V{from} to V{target}\");\n    }\n    if target > CURRENT_SCHEMA_VERSION {\n        anyhow::bail!(\n            \"target V{target} exceeds CURRENT_SCHEMA_VERSION (V{CURRENT_SCHEMA_VERSION})\"\n        );\n    }\n\n    let mut cur = value;\n    for step in &MIGRATION_STEPS[from as usize..target as usize] {\n        cur = step(cur)?;\n    }\n    Ok(cur)\n}\n\npub(crate) fn sync_table(doc: &mut toml_edit::Table, new: &toml::Table) {\n    // Drop keys not present in new\n    let to_remove: Vec<String> = doc\n        .iter()\n        .map(|(k, _)| k.to_string())\n        .filter(|k| !new.contains_key(k))\n        .collect();","sourceCodeStart":811,"sourceCodeEnd":847,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-config/src/migration.rs#L811-L847","documentation":"run_chain_until refuses any target above CURRENT_SCHEMA_VERSION because migration steps only exist up to the compiled version (V3). This is the bounds check that keeps the MIGRATION_STEPS[from..target] slice from indexing past its end, and it catches requests for schema versions the running binary cannot produce.","triggerScenarios":"Calling run_chain_until(value, from, target) with target > 3 — e.g. requesting generate() at V4 on a V3 binary, or forwarding a hardcoded future version that outlived the binary it was written against.","commonSituations":"Code written against a newer ZeroClaw that hardcodes a higher target version; a user-supplied version from config or CLI forwarded unclamped into the migration chain.","solutions":["Use CURRENT_SCHEMA_VERSION as the target instead of a literal number.","Upgrade the binary if you genuinely need the newer schema version.","Validate or clamp the target argument before calling the chain."],"exampleFix":"// before\nlet migrated = run_chain_until(value, from, 4)?; // target exceeds CURRENT_SCHEMA_VERSION\n\n// after\nlet migrated = run_chain_until(value, from, CURRENT_SCHEMA_VERSION)?;","handlingStrategy":"validation","validationCode":"// never hardcode a schema literal; derive it\nlet target = target.min(CURRENT_SCHEMA_VERSION);\nassert!(target >= from, \"downgrades unsupported\");\nlet migrated = run_chain_until(value, from, target)?;","typeGuard":null,"tryCatchPattern":"match run_chain_until(value, from, target) {\n    Err(e) if e.to_string().contains(\"exceeds CURRENT_SCHEMA_VERSION\") => {\n        // retry with target = CURRENT_SCHEMA_VERSION\n    }\n    other => other?,\n}","preventionTips":["Always pass CURRENT_SCHEMA_VERSION rather than a number literal.","Validate externally sourced version values against the binary's supported range.","Remember the supported ceiling changes with the binary version; re-check after upgrades."],"tags":["migration","version-bounds","config"],"backgroundTag":"migration-target-out-of-range","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}