nautechsystems/nautilus_trader · error
from_json not implemented for {}
Error message
from_json not implemented for {} What it means
The CustomDataTrait::from_json default implementation is a stub that always fails. Types that do not override from_json cannot be deserialized from JSON, and the error names the concrete Rust type so the developer knows which registration/impl is missing.
Source
Thrown at crates/model/src/data/custom.rs:341
/// Returns the type name used in serialized form (e.g. in the `"type"` field).
#[must_use]
fn type_name_static() -> &'static str
where
Self: Sized,
{
std::any::type_name::<Self>()
}
/// Deserializes from a JSON value into an Arc'd trait object.
///
/// # Errors
/// Returns an error if JSON deserialization fails.
fn from_json(_value: serde_json::Value) -> anyhow::Result<Arc<dyn CustomDataTrait>>
where
Self: Sized,
{
anyhow::bail!(
"from_json not implemented for {}",
std::any::type_name::<Self>()
)
}
}
/// Registers a custom data type for JSON deserialization. When `Data::deserialize`
/// sees the type name returned by `T::type_name_static()`, it will call `T::from_json`.
///
/// # Errors
/// Returns an error if the type is already registered.
pub fn register_custom_data_json<T: CustomDataTrait + Sized>() -> anyhow::Result<()> {
let type_name = T::type_name_static();
register_json_deserializer(type_name, Box::new(|value| T::from_json(value)))
}
/// Registers a custom data type for JSON deserialization if not already registered.
/// Idempotent: safe to call multiple times for the same type (e.g. module init).View on GitHub (pinned to 18893faf8b)
Solutions
- Implement from_json for the concrete type so it reconstructs the struct from the serde_json::Value.
- If deserialization is genuinely unsupported, avoid JSON round-trips for this type and use the serialization-only path.
- Check the type registry: register a JSON deserializer via register_json_deserializer so the framework routes to a working implementation.
Example fix
// before
fn from_json(_value: serde_json::Value) -> anyhow::Result<Arc<dyn CustomDataTrait>> {
// default stub, always bails
}
// after
fn from_json(value: serde_json::Value) -> anyhow::Result<Arc<dyn CustomDataTrait>> {
let data: MyData = serde_json::from_value(value)?;
Ok(Arc::new(data))
} Defensive patterns
Strategy: try-catch
Validate before calling
// Rust — fail fast at startup if the type lacks a real from_json
fn supports_from_json<T: CustomDataTrait>() -> bool { std::any::type_name::<T>().len() > 0 } // pair with a round-trip test
// Prefer: write a test that serializes and deserializes each custom type Try / catch
// Rust
match MyData::from_json(value) {
Ok(data) => data,
Err(e) if e.to_string().starts_with("from_json not implemented") => {
return Err(anyhow::anyhow!("custom type lacks JSON deserialization; add an impl"))
}
Err(e) => return Err(e),
} Prevention
- When adding a custom data type, implement to_json and from_json together.
- Add a serialize/deserialize round-trip unit test per custom type.
- Register a JSON deserializer for every type exposed to persistence.
When it happens
Trigger: Calling from_json on a custom data type whose impl uses the default trait method instead of providing a real JSON deserializer.
Common situations: Adding a new custom data type and implementing serialization but forgetting the deserialization side; round-tripping custom data through JSON persistence where one direction was implemented.
Related errors
- CustomData JSON missing 'payload' field
- Failed to decode position replay state: {e}
- Invalid data_type JSON: {e}
- Failed to import json: {e}
- Failed to parse JSON: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/2425dff0f059df4c.
Report an issue: GitHub.