Hmbown/CodeWhale · error · io::Error
<dynamic: wrapped serde_json serialization error>
Error message
<dynamic: wrapped serde_json serialization error>
What it means
publish_legacy_spillover_ownership serializes the LegacySpilloverOwnership struct (schema version, origin session, digest, size) with serde_json::to_vec_pretty before an atomic write. Serialization errors are wrapped in io::ErrorKind::InvalidData with the serde error attached. Given the simple field set, failures point to a type serde_json cannot represent, most commonly a non-string map key or invalid float introduced by a schema change.
Solutions
- Read the wrapped serde error to find the offending field in LegacySpilloverOwnership.
- Change non-string map keys to String/String-keyed maps and sanitize float fields (no NaN/Infinity).
- Use #[serde(skip_serializing_if = "Option::is_none")] or a custom Serialize for awkward types.
- Pin the struct with a round-trip unit test so future schema changes cannot silently break serialization.
Example fix
// before
struct LegacySpilloverOwnership { tags: HashMap<u32, String>, ... }
// after
struct LegacySpilloverOwnership { tags: BTreeMap<String, String>, ... } Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check types serde_json cannot represent when extending the struct // reject non-string map keys and non-finite floats before constructing LegacySpilloverOwnership
Try / catch
// rust
let encoded = serde_json::to_vec_pretty(&ownership)
.map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))?; // log wrapped serde error to find the field Prevention
- Use only JSON-native types (String keys, finite numbers) in LegacySpilloverOwnership fields.
- Run a serialize/deserialize round-trip test whenever the struct's schema changes.
When it happens
Trigger: apply_spillover_inner -> publish_legacy_spillover_ownership when serde_json::to_vec_pretty(&ownership) errors — e.g. after adding a field with a non-JSON-compatible type (HashMap<u64,_>, f64::NAN) or a failing custom Serialize impl.
Common situations: Recent schema evolution of LegacySpilloverOwnership added a problematic field; NaN/Infinity sizes or digests stored as floats; a custom serializer returning Err.
Understand the failure class
Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.
Related errors
- (serde_json serialization error wrapped as…
- <dynamic: wrapped serde_json serialization error>
- (serde_json deserialization error wrapped as…
- <serde_json serialization error>
- serialize
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/507b15dca68820cf.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tools/truncate.rs:153
payload_path: &Path,
session_id: &str,
bytes: &[u8],
) -> io::Result<PathBuf> {
if session_id.trim().is_empty() {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"legacy spillover ownership requires a session id",
));
}
let ownership = LegacySpilloverOwnership {
schema_version: LEGACY_SPILLOVER_OWNER_SCHEMA_VERSION,
origin_session: session_id.to_string(),
digest: crate::hashing::sha256_hex(bytes),
size_bytes: bytes.len().try_into().unwrap_or(u64::MAX),
};
let sidecar = legacy_spillover_ownership_path(payload_path);
let encoded = serde_json::to_vec_pretty(&ownership)
.map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))?;
crate::utils::write_atomic(&sidecar, &encoded)?;
Ok(sidecar)
}
pub(crate) fn read_legacy_spillover_ownership(
payload_path: &Path,
) -> io::Result<LegacySpilloverOwnership> {
let sidecar = legacy_spillover_ownership_path(payload_path);
if std::fs::symlink_metadata(&sidecar)?
.file_type()
.is_symlink()
{
return Err(io::Error::new(
io::ErrorKind::PermissionDenied,
"legacy spillover ownership sidecar must not be a symlink",
));
}
let ownership = serde_json::from_slice::<LegacySpilloverOwnership>(&std::fs::read(sidecar)?)View on GitHub (pinned to 73e0f67d83)