cross-rs/cross · error · eyre::ErrReport
failed to serialize CrossToml as object
Error message
failed to serialize CrossToml as object
What it means
`CrossToml::to_map` serializes the TOML config into a `serde_json::Value` and expects it to be a JSON object (map). If the serialized value is not an object (e.g. an array or scalar), it fails, because the merge machinery (`merge`) can only combine map-shaped configs.
Solutions
- Ensure the cross.toml top level is a TOML table (key/value sections), not an array or bare value.
- If constructing CrossToml programmatically, build it as a map/struct that serializes to an object.
- Inspect the chained error ("could not convert CrossToml to serde_json::Value") for the underlying serialization failure.
Example fix
// before (invalid top-level TOML) [[config]] key = "value" // after [config] key = "value"
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure top-level cross config is a table
if !raw_toml.trim_start().starts_with('[') && raw_toml.contains('=') && !raw_toml.contains('\n[') { /* likely scalar top-level, reject */ } Try / catch
match CrossToml::merge(...) {
Ok(t) => t,
Err(e) => { eprintln!("config merge failed: {e:?>}"); return Err(e); }
} Prevention
- Keep cross.toml top level a TOML table with named sections.
- Round-trip programmatic configs through to_map in unit tests.
- Log the full eyre report chain to see the underlying serialization cause.
When it happens
Trigger: Calling `merge` on a `CrossToml` whose serialization does not yield a JSON object — typically an internal invariant violation when the TOML deserialized into a non-table top-level shape.
Common situations: A cross.toml whose top level is not a table (rare, usually only via programmatic construction or corrupted config), or a bug in the merge pipeline passing a non-map value.
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
- found unused key(s) in Cross configuration
- unable to find provided nix-store directory
- unsupported rust target for file
- invalid linux version, got
- a target named " " is mentioned in the Cross configuration…
AI-assisted analysis of cross-rs/cross@8c1a8aa4b6 (2026-09-13).
Data as JSON: /api/errors/2a75544e366a8156.
Report an issue: GitHub.
Appendix: source
Thrown at src/cross_toml.rs:220
unused.clone().into_iter().collect::<Vec<_>>().join(", ")
))?;
}
Ok((cfg, unused))
}
/// Merges another [`CrossToml`] into `self` and returns a new merged one
pub fn merge(self, other: CrossToml) -> Result<CrossToml> {
type ValueMap = serde_json::Map<String, serde_json::Value>;
fn to_map<S: Serialize>(s: S) -> Result<ValueMap> {
if let Some(obj) = serde_json::to_value(s)
.wrap_err("could not convert CrossToml to serde_json::Value")?
.as_object()
{
Ok(obj.clone())
} else {
eyre::bail!("failed to serialize CrossToml as object");
}
}
fn from_map<D: DeserializeOwned>(map: ValueMap) -> Result<D> {
let value = serde_json::to_value(map)
.wrap_err("could not convert ValueMap to serde_json::Value")?;
serde_json::from_value(value)
.wrap_err("could not deserialize serde_json::Value to CrossToml")
}
// merge 2 objects. y has precedence over x.
fn merge_objects(x: &mut ValueMap, y: &ValueMap) -> Option<()> {
// we need to iterate over both keys, so we need a full deduplication
let keys: BTreeSet<String> = x.keys().chain(y.keys()).cloned().collect();
for key in keys {
let in_x = x.contains_key(&key);
let in_y = y.contains_key(&key);
if !in_x && in_y {View on GitHub (pinned to 8c1a8aa4b6)