nautechsystems/nautilus_trader · error · anyhow::Error
{e}
Error message
{e} What it means
Raised in `load_custom_data` when `CustomData::from_json_bytes` fails to deserialize a row's `value` JSON into a CustomData instance. The message is the inner error verbatim (`{e}`), typically a serde error about missing fields, wrong types, or an unknown data type name in the stored JSON.
Source
Thrown at crates/infrastructure/src/sql/queries.rs:1730
AND identifier = ''
ORDER BY ts_init ASC"#,
)
.bind(type_name)
.bind(short_type)
.bind(&metadata_json)
.fetch_all(pool)
.await
}
}
.map_err(|e| anyhow::anyhow!("Failed to load custom data: {e}"))?;
let mut results = Vec::with_capacity(rows.len());
for row in rows {
let value_json: serde_json::Value = row.try_get("value")?;
let json_bytes = serde_json::to_vec(&value_json)
.map_err(|e| anyhow::anyhow!("Failed to serialize JSON: {e}"))?;
let custom =
CustomData::from_json_bytes(&json_bytes).map_err(|e| anyhow::anyhow!("{e}"))?;
results.push(custom);
}
Ok(results)
}
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Read the inner deserialization error to see which field/type failed.
- Ensure the data_type filter matches how the rows were originally written.
- Write a migration/backfill to transform old payload shapes to the current CustomData schema.
- Pin compatible versions of the data model crate between writer and reader.
Example fix
// before
let custom = CustomData::from_json_bytes(&json_bytes).map_err(|e| anyhow::anyhow!("{e}"))?;
// after
let custom = match CustomData::from_json_bytes(&json_bytes) {
Ok(c) => c,
Err(e) => { tracing::warn!("skipping incompatible custom data row: {e}"); continue; }
}; Defensive patterns
Strategy: try-catch
Validate before calling
// check the stored JSON has the fields CustomData requires
let v: serde_json::Value = row.try_get("value")?;
anyhow::ensure!(v.get("data_type").is_some(), "stored row missing data_type"); Type guard
fn is_compatible_custom_data(v: &serde_json::Value) -> bool {
v.get("data_type").and_then(|d| d.get("type_name")).is_some()
} Try / catch
match CustomData::from_json_bytes(&json_bytes) {
Ok(c) => results.push(c),
Err(e) => {
tracing::warn!("skipping incompatible custom data row: {e}");
// decide: skip vs fail-fast depending on workload
}
} Prevention
- Use the same data model crate version for writers and readers
- Run schema migrations when payload shape changes
- Backfill/migrate old rows to the current schema
- Verify data_type filters match how rows were written
When it happens
Trigger: Calling `load_custom_data` where a stored `value` JSONB does not match the current CustomData schema — missing required fields after a model change, wrong data type requested, or rows written by a different library version.
Common situations: Schema evolution: stored payloads from an older version lack newly required fields; querying with the wrong data_type so rows deserialize into the wrong model; hand-edited rows in the database.
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 deserialization error: {e}
- Failed to decode position replay state: {e}
- Failed to deserialize instrument payload
- from_json not implemented for {}
- Failed to parse {method} response
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/a10312a36522aa3a.
Report an issue: GitHub.