nautechsystems/nautilus_trader · error
Invalid data_type JSON: {e}
Error message
Invalid data_type JSON: {e} What it means
`DataType::from_persistence_json` parses a persisted `DataType` from a JSON string. If the string is not syntactically valid JSON, `serde_json::from_str` fails and the serde error is wrapped as `Invalid data_type JSON: {e}`.
Source
Thrown at crates/model/src/data/mod.rs:805
if let Some(ref id) = self.identifier {
map.insert(
"identifier".to_string(),
serde_json::Value::String(id.clone()),
);
}
serde_json::to_string(&serde_json::Value::Object(map))
}
/// Deserializes from JSON produced by `to_persistence_json`.
/// Accepts legacy JSON with `topic` (ignored); topic is rebuilt from `type_name` + metadata.
///
/// # Errors
///
/// Returns an error if the string is not valid JSON or missing required fields.
pub fn from_persistence_json(s: &str) -> Result<Self, anyhow::Error> {
let value: serde_json::Value =
serde_json::from_str(s).map_err(|e| anyhow::anyhow!("Invalid data_type JSON: {e}"))?;
let obj = value
.as_object()
.ok_or_else(|| anyhow::anyhow!("data_type must be a JSON object"))?;
let type_name = obj
.get("type_name")
.and_then(|v| v.as_str())
.ok_or_else(|| anyhow::anyhow!("data_type must have type_name"))?;
let metadata = obj.get("metadata").and_then(|m| {
if m.is_null() {
None
} else {
let p: Params = serde_json::from_value(m.clone()).ok()?;
if p.is_empty() { None } else { Some(p) }
}
});
let identifier = obj
.get("identifier")
.and_then(|v| v.as_str())View on GitHub (pinned to 18893faf8b)
Solutions
- Print the failing string (from the serde error offset) and validate it with a JSON linter to find the syntax fault.
- Check the source file for truncation/corruption; restore from backup or re-persist the DataType.
- Ensure you pass only the JSON document, not surrounding log lines or a Python/Rust debug repr.
- Strip BOM/whitespace and confirm file encoding (UTF-8) before parsing.
Example fix
// before
let dt = DataType::from_persistence_json(&raw_line)?;
// after
let trimmed = raw_line.trim().trim_start_matches('\u{feff}');
let dt = DataType::from_persistence_json(trimmed)
.with_context(|| format!("bad DataType JSON: {trimmed}"))?; Defensive patterns
Strategy: try-catch
Validate before calling
fn is_plausible_json(s: &str) -> bool {
serde_json::from_str::<serde_json::Value>(s.trim().trim_start_matches('\u{feff}')).is_ok()
} Try / catch
match DataType::from_persistence_json(s) {
Ok(dt) => dt,
Err(e) => { log::warn!("skipping bad DataType record: {e}"); continue; }
}; Prevention
- Write persistence files atomically (temp file + rename) to avoid truncation.
- Persist only the library's own serialized form, never debug reprs or log lines.
- Validate JSON files at load time and quarantine bad records.
When it happens
Trigger: Calling `DataType::from_persistence_json` with a string that is truncated, empty, concatenated with other log text, or otherwise not valid JSON (e.g. a single-quoted or comment-containing string).
Common situations: Reading a corrupted or partially written catalog/journal file; copy-pasting a DataType repr instead of its JSON; a persistence file written by an older version with a different format; loading a file with BOM or trailing garbage bytes.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
Related errors
- from_json not implemented for {}
- Failed to decode position replay state: {e}
- data_type must be a JSON object
- CustomData JSON missing 'payload' field
- Invalid NodeState value
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/2c0e76adb908e276.
Report an issue: GitHub.