Hmbown/CodeWhale · error · std::io::Error
(serde_json deserialization error wrapped as…
Error message
(serde_json deserialization error wrapped as io::ErrorKind::InvalidData)
What it means
`load_offline_queue_state` reads the parked queue JSON and deserializes it with `serde_json::from_str::<OfflineQueueState>`; a malformed file surfaces as `io::ErrorKind::InvalidData` wrapping the serde error. A missing file is handled separately and yields `Ok(None)`, so this error always means the file exists but is not valid JSON/does not match the struct.
Solutions
- Read the wrapped serde message to find the exact field/format mismatch.
- Delete the corrupted parked-queue file for that session (queue contents are lost) and let the session recreate it.
- Restore the file from backup if the queued input matters.
- Avoid hand-editing checkpoint files; let the app write them.
Defensive patterns
Strategy: try-catch
Validate before calling
if let Ok(txt) = std::fs::read_to_string(path) {
if serde_json::from_str::<serde_json::Value>(&txt).is_err() {
eprintln!("parked queue file is corrupt; delete or restore it");
}
} Try / catch
match manager.load_offline_queue_state(id) {
Err(e) if e.kind() == std::io::ErrorKind::InvalidData => {
// corrupt file: back it up, delete, continue without queued input
}
other => other?,
} Prevention
- Never hand-edit parked queue files.
- Ensure writes are atomic (the library uses write_atomic) — avoid copying partial files around.
- Back up checkpoint directories before tooling experiments.
When it happens
Trigger: Calling `load_offline_queue_state` for a session whose parked-queue file is truncated, partially written, hand-edited, or has fields of the wrong type/shape.
Common situations: A crash mid-write on filesystems without atomic rename guarantees; manual edits to checkpoint files; a queue file written by an incompatible older format missing required fields.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- (serde_json serialization error wrapped as…
- <dynamic: wrapped serde_json parse error>
- Offline queue schema v
- <serde_json deserialization error>
- (serde_json deserialization error wrapped as…
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/9f9441233ae82d1a.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/session_manager.rs:2212
}
Ok(())
}
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.View on GitHub (pinned to 433685b202)