Hmbown/CodeWhale · error · std::io::Error

Offline queue schema v

Error message

Offline queue schema v{state.schema_version} is newer than supported v{CURRENT_QUEUE_SCHEMA_VERSION}

What it means

After deserializing a parked offline queue, the loader checks `state.schema_version > CURRENT_QUEUE_SCHEMA_VERSION` and rejects newer formats with `io::ErrorKind::InvalidData`. Like the session-schema check, this prevents an older binary from misreading fields written by a newer release.

Solutions

  1. Upgrade to the build that wrote the queue state.
  2. Start fresh: remove the parked queue file for that session if its contents are no longer needed.
  3. Before downgrading, drain/flush the offline queue in the newer version.
Defensive patterns

Strategy: try-catch

Validate before calling

let v: serde_json::Value = serde_json::from_str(&std::fs::read_to_string(path)?)?;
if v["schema_version"].as_u64().unwrap_or(0) > CURRENT_QUEUE_SCHEMA_VERSION {
    eprintln!("parked queue too new");
}

Try / catch

match manager.load_offline_queue_state(id) {
    Err(e) if e.to_string().contains("newer than supported") => {
        // upgrade binary or discard the parked queue
    }
    other => other?,
}

Prevention

When it happens

Trigger: Loading a parked offline queue whose `schema_version` exceeds the current binary's `CURRENT_QUEUE_SCHEMA_VERSION` — typically after a downgrade or switching to an older branch.

Common situations: Rolling the binary back while a queued-input state was parked by a newer version; syncing checkpoint directories between machines running different versions.

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@433685b202 (2026-09-15). Data as JSON: /api/errors/61f6a2863ea2db5e. Report an issue: GitHub.

Appendix: source

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

    }

    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 433685b202)