xai-org/grok-build · error · std::io::Error
<serde_json serialization error for Summary>
Error message
<serde_json serialization error for Summary>
What it means
write_summary_atomic serializes the Summary struct to pretty JSON before atomically writing it; a serde_json serialization failure (e.g. a non-string map key or unserializable value inside Summary) is wrapped as io::ErrorKind::InvalidData. With a plain derive-based struct this is rare and usually indicates a Map with non-string keys or a custom Serialize impl that fails.
Source
Thrown at crates/codegen/xai-grok-shell/src/session/storage/summary_write.rs:419
.truncate(false)
.open(path)
}
fn read_summary(path: &Path) -> io::Result<Summary> {
let bytes = std::fs::read(path)?;
if bytes.is_empty() {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("summary.json is empty (0 bytes): {}", path.display()),
));
}
serde_json::from_slice::<Summary>(&bytes)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
}
fn write_summary_atomic(summary_path: &Path, summary: &Summary) -> io::Result<()> {
let bytes = serde_json::to_vec_pretty(summary)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
crate::session::storage::write_bytes_atomic(summary_path, &bytes)
}
#[cfg(test)]
thread_local! {
static RESTORE_MTIME_FAULT: std::cell::Cell<bool> = const { std::cell::Cell::new(false) };
}
#[cfg(test)]
pub(crate) fn fail_next_restore_summary_mtime() {
RESTORE_MTIME_FAULT.set(true);
}
fn restore_summary_mtime(path: &Path, mtime: std::time::SystemTime) -> io::Result<()> {
#[cfg(test)]
if RESTORE_MTIME_FAULT.replace(false) {
return Err(io::Error::other("injected mtime restore failure"));
}View on GitHub (pinned to bc7f02eddd)
Solutions
- Inspect the inner serde error message to find the unserializable field
- Change non-string map keys to String (or use #[serde(with)] helpers)
- Ensure all Summary fields' types implement Serialize compatibly with JSON
- Add a unit test that serializes a fully-populated Summary to catch regressions
Example fix
// before
struct Summary { meta: HashMap<Uuid, String> }
// after
struct Summary { meta: HashMap<String, String> } // or BTreeMap<String, _> with uuid::Uuid keys via serde
let meta: HashMap<String, String> = original.into_iter().map(|(k, v)| (k.to_string(), v)).collect(); Defensive patterns
Strategy: try-catch
Validate before calling
// pre-validate: ensure all map keys in data feeding Summary are strings assert!(summary.meta.keys().all(|k| k.parse::<uuid::Uuid>().is_ok() || k.is_empty()) || true); // prefer converting keys upstream type Check = fn(&Summary) -> Result<(), serde_json::Error>; let validate: Check = |s| serde_json::to_value(s).map(|_| ());
Type guard
fn serializable(s: &Summary) -> bool {
serde_json::to_vec_pretty(s).is_ok()
} Try / catch
match write_summary_atomic(&path, &summary) {
Ok(()) => (),
Err(e) if e.kind() == io::ErrorKind::InvalidData => {
eprintln!("Summary not JSON-serializable: {e}");
}
Err(e) => return Err(e),
} Prevention
- Keep Summary field types JSON-friendly (string keys in maps)
- Add a round-trip serialization unit test for a fully populated Summary
- Avoid embedding serde_json::Value with arbitrary user data without normalization
- Convert Uuid/i32 map keys to String before storing in Summary
When it happens
Trigger: Calling write_summary_atomic (via repair_worktree_identity or read_modify_write) with a Summary containing data serde_json cannot represent — e.g. a HashMap with non-string keys, an untagged enum hitting an unserializable variant, or a custom Serialize impl returning an error.
Common situations: Introducing a BTreeMap<HashMap<i32,_>,..> or serde_json::Value::Number-typed key into Summary; nesting types with non-string map keys; building Summary from arbitrary parsed JSON with wrong key types.
Related errors
- <serde_json deserialization error for summary.json>
- failed to build request: {e}
- Compaction checkpoint file corrupt: {checkpoint_path}. Canno
- summary.json is empty (0 bytes): {}
- {}
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/7430ed5e353d92f0.
Report an issue: GitHub.