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

  1. Implement from_json for the concrete type so it reconstructs the struct from the serde_json::Value.
  2. If deserialization is genuinely unsupported, avoid JSON round-trips for this type and use the serialization-only path.
  3. 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 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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/2425dff0f059df4c. Report an issue: GitHub.