{"record":{"id":"8d54ed0b421ed1b2","repo":"Hmbown/CodeWhale","slug":"thread-schema-v-is-newer-than-supported-v","errorCode":null,"errorMessage":"Thread schema v{} is newer than supported v{}","messagePattern":"Thread schema v(.+?) is newer than supported v(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/runtime_threads.rs","lineNumber":1293,"sourceCode":"        remove_file_if_exists(&self.turn_path(turn_id)?)\n    }\n\n    fn remove_thread(&self, thread_id: &str) -> Result<()> {\n        remove_file_if_exists(&self.thread_path(thread_id)?)\n    }\n\n    fn remove_item(&self, item_id: &str) -> Result<()> {\n        remove_file_if_exists(&self.item_path(item_id)?)\n    }\n\n    pub fn load_thread(&self, thread_id: &str) -> Result<ThreadRecord> {\n        let path = self.thread_path(thread_id)?;\n        let raw = read_store_file(&path)\n            .with_context(|| format!(\"Failed to read thread {}\", path.display()))?;\n        let record: ThreadRecord = serde_json::from_str(&raw)\n            .with_context(|| format!(\"Failed to parse thread {}\", path.display()))?;\n        if record.schema_version > CURRENT_RUNTIME_SCHEMA_VERSION {\n            bail!(\n                \"Thread schema v{} is newer than supported v{}\",\n                record.schema_version,\n                CURRENT_RUNTIME_SCHEMA_VERSION\n            );\n        }\n        Ok(record)\n    }\n\n    pub fn load_turn(&self, turn_id: &str) -> Result<TurnRecord> {\n        let path = self.turn_path(turn_id)?;\n        let raw = read_store_file(&path)\n            .with_context(|| format!(\"Failed to read turn {}\", path.display()))?;\n        let record: TurnRecord = serde_json::from_str(&raw)\n            .with_context(|| format!(\"Failed to parse turn {}\", path.display()))?;\n        if record.schema_version > CURRENT_RUNTIME_SCHEMA_VERSION {\n            bail!(\n                \"Turn schema v{} is newer than supported v{}\",\n                record.schema_version,","sourceCodeStart":1275,"sourceCodeEnd":1311,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/runtime_threads.rs#L1275-L1311","documentation":"load_thread reads a thread JSON file and compares its schema_version against CURRENT_RUNTIME_SCHEMA_VERSION (currently 2). A record written by a newer Codewhale whose schema major is higher cannot be interpreted correctly, so loading is refused rather than mis-parsed. This is forward-incompatibility detection for the on-disk thread store.","triggerScenarios":"Calling RuntimeThreadStore::load_thread(thread_id) where the stored thread JSON has schema_version > 2; typically after downgrading Codewhale or pointing the data dir at a store written by a newer build.","commonSituations":"Rolling back to an older release while keeping the same task-data directory; sharing a data dir between two installed versions; opening a backup made by a newer version.","solutions":["Upgrade Codewhale to at least the version that wrote the store, then retry.","Point the runtime at a fresh data directory if you intentionally need the older version and do not need old threads.","Check the schema_version field in the thread JSON to confirm which version wrote it before choosing rollback vs upgrade."],"exampleFix":"# before\n# data dir last written by codewhale 3.x, running 2.x\ncodewhale threads show <id>   # bails: Thread schema v3 is newer than supported v2\n\n# after\n# upgrade to the version that wrote the store\ncodewhale upgrade && codewhale threads show <id>","handlingStrategy":"validation","validationCode":"// Rust: probe a record's schema version before handing it to the store\nfn schema_version_of(path: &std::path::Path) -> Option<u32> {\n    let raw = std::fs::read_to_string(path).ok()?;\n    serde_json::from_str::<serde_json::Value>(&raw).ok()?\n        .get(\"schema_version\")?\n        .as_u64()\n        .map(|v| v as u32)\n}\n\nif let Some(v) = schema_version_of(&thread_path) {\n    anyhow::ensure!(v <= 2, \"thread {thread_id} needs schema v{v}; upgrade Codewhale\");\n}\nlet record = store.load_thread(thread_id)?;","typeGuard":null,"tryCatchPattern":"// Rust: distinguish version rejection from IO/parse errors and surface an upgrade hint\nmatch store.load_thread(thread_id) {\n    Ok(record) => Ok(record),\n    Err(err) if err.to_string().contains(\"newer than supported\") => {\n        Err(anyhow::anyhow!(\"store written by a newer Codewhale; upgrade before reading: {err}\"))\n    }\n    Err(err) => Err(err),\n}","preventionTips":["Never reopen a data directory with an older binary after an upgrade.","Check schema_version in exported/shared JSON before importing it.","Pin each Codewhale version to its own data dir, or migrate forward only."],"tags":["schema","versioning","persistence","thread-store","rust"],"backgroundTag":"schema-version-mismatch","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}