{"record":{"id":"f9165e51a45858f5","repo":"Hmbown/CodeWhale","slug":"offline-queue-schema-v-is-newer-than-supported-v","errorCode":null,"errorMessage":"Offline queue schema v{} is newer than supported v{}","messagePattern":"Offline queue schema v(.+?) is newer than supported v(.+?)","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/session_manager.rs","lineNumber":2335,"sourceCode":"    }\n\n    fn validated_offline_queue_path(&self, session_id: &str) -> std::io::Result<PathBuf> {\n        let trimmed = self.validated_session_id(session_id)?;\n        Ok(self\n            .checkpoints_dir()\n            .join(format!(\"{trimmed}{OFFLINE_QUEUE_SUFFIX}\")))\n    }\n\n    fn read_offline_queue_file(path: &Path) -> std::io::Result<Option<OfflineQueueState>> {\n        let content = match fs::read_to_string(path) {\n            Ok(content) => content,\n            Err(error) if error.kind() == io::ErrorKind::NotFound => return Ok(None),\n            Err(error) => return Err(error),\n        };\n        let state: OfflineQueueState = serde_json::from_str(&content)\n            .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;\n        if state.schema_version > CURRENT_QUEUE_SCHEMA_VERSION {\n            return Err(std::io::Error::new(\n                std::io::ErrorKind::InvalidData,\n                format!(\n                    \"Offline queue schema v{} is newer than supported v{}\",\n                    state.schema_version, CURRENT_QUEUE_SCHEMA_VERSION\n                ),\n            ));\n        }\n        Ok(Some(state))\n    }\n\n    /// Migrate the pre-per-session global queue (`checkpoints/offline_queue.json`).\n    ///\n    /// It holds user-authored text, so it is adopted only by the session it was\n    /// stamped for, and it is removed only once this session's copy is durably\n    /// written. A queue stamped for someone else — or for nobody — is left\n    /// exactly where it is, still readable, for its owner to claim.\n    fn adopt_legacy_offline_queue(\n        &self,","sourceCodeStart":2317,"sourceCodeEnd":2353,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/session_manager.rs#L2317-L2353","documentation":"After deserializing an offline queue checkpoint, load_offline_queue_state rejects files whose schema_version exceeds CURRENT_QUEUE_SCHEMA_VERSION with a clear forward-compatibility error instead of silently misreading newer data. This is an intentional guard: newer formats may have incompatibly-shaped fields.","triggerScenarios":"Calling load_offline_queue_state against a checkpoint written by a newer build (higher schema_version) than the currently running binary.","commonSituations":"Downgrading the application while a session checkpoint from a newer version exists; switching branches or rolling back a release on a shared machine.","solutions":["Upgrade the application back to (or past) the version that wrote the checkpoint.","If the downgrade is intentional, back up and remove the checkpoint file so the session starts with an empty queue.","Optionally write a small migration: parse the JSON manually, drop/transform unknown fields, and rewrite with the current schema_version before calling load."],"exampleFix":"// before\nlet state = manager.load_offline_queue_state(id)?;\n// after\nlet state = match manager.load_offline_queue_state(id) {\n    Err(e) if e.to_string().contains(\"newer than supported\") => {\n        eprintln!(\"checkpoint from newer version; starting empty\");\n        None\n    }\n    other => other?,\n};","handlingStrategy":"fallback","validationCode":"fn schema_ok(path: &Path, supported: u32) -> std::io::Result<bool> {\n    let v: serde_json::Value = serde_json::from_str(&std::fs::read_to_string(path)?)?;\n    Ok(v.get(\"schema_version\").and_then(|s| s.as_u64()).unwrap_or(0) <= supported as u64)\n}","typeGuard":null,"tryCatchPattern":"match load_offline_queue_state(id) {\n    Err(e) if e.to_string().contains(\"newer than supported\") => {\n        log::warn!(\"checkpoint written by newer version; ignoring\");\n        None\n    }\n    other => other?,\n}","preventionTips":["Avoid downgrading the app while newer checkpoints exist; move them aside first.","Bump schema_version only with a documented migration path.","Keep CURRENT_QUEUE_SCHEMA_VERSION in sync with release notes so users expect the guard."],"tags":["schema-version","forward-compatibility","offline-queue","downgrade"],"backgroundTag":"schema-validation-failed","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}