Hmbown/CodeWhale · error · io::Error

Offline queue schema v

Error message

Offline queue schema v{} is newer than supported v{}

What it means

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.

Solutions

  1. Upgrade the application back to (or past) the version that wrote the checkpoint.
  2. If the downgrade is intentional, back up and remove the checkpoint file so the session starts with an empty queue.
  3. Optionally write a small migration: parse the JSON manually, drop/transform unknown fields, and rewrite with the current schema_version before calling load.

Example fix

// before
let state = manager.load_offline_queue_state(id)?;
// after
let state = match manager.load_offline_queue_state(id) {
    Err(e) if e.to_string().contains("newer than supported") => {
        eprintln!("checkpoint from newer version; starting empty");
        None
    }
    other => other?,
};
Defensive patterns

Strategy: fallback

Validate before calling

fn schema_ok(path: &Path, supported: u32) -> std::io::Result<bool> {
    let v: serde_json::Value = serde_json::from_str(&std::fs::read_to_string(path)?)?;
    Ok(v.get("schema_version").and_then(|s| s.as_u64()).unwrap_or(0) <= supported as u64)
}

Try / catch

match load_offline_queue_state(id) {
    Err(e) if e.to_string().contains("newer than supported") => {
        log::warn!("checkpoint written by newer version; ignoring");
        None
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling load_offline_queue_state against a checkpoint written by a newer build (higher schema_version) than the currently running binary.

Common situations: Downgrading the application while a session checkpoint from a newer version exists; switching branches or rolling back a release on a shared machine.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/f9165e51a45858f5. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/session_manager.rs:2335

    }

    fn validated_offline_queue_path(&self, session_id: &str) -> std::io::Result<PathBuf> {
        let trimmed = self.validated_session_id(session_id)?;
        Ok(self
            .checkpoints_dir()
            .join(format!("{trimmed}{OFFLINE_QUEUE_SUFFIX}")))
    }

    fn read_offline_queue_file(path: &Path) -> std::io::Result<Option<OfflineQueueState>> {
        let content = match fs::read_to_string(path) {
            Ok(content) => content,
            Err(error) if error.kind() == io::ErrorKind::NotFound => return Ok(None),
            Err(error) => return Err(error),
        };
        let state: OfflineQueueState = serde_json::from_str(&content)
            .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
        if state.schema_version > CURRENT_QUEUE_SCHEMA_VERSION {
            return Err(std::io::Error::new(
                std::io::ErrorKind::InvalidData,
                format!(
                    "Offline queue schema v{} is newer than supported v{}",
                    state.schema_version, CURRENT_QUEUE_SCHEMA_VERSION
                ),
            ));
        }
        Ok(Some(state))
    }

    /// Migrate the pre-per-session global queue (`checkpoints/offline_queue.json`).
    ///
    /// It holds user-authored text, so it is adopted only by the session it was
    /// stamped for, and it is removed only once this session's copy is durably
    /// written. A queue stamped for someone else — or for nobody — is left
    /// exactly where it is, still readable, for its owner to claim.
    fn adopt_legacy_offline_queue(
        &self,

View on GitHub (pinned to 73e0f67d83)