nautechsystems/nautilus_trader · error

serialized order did not contain an object core

Error message

serialized order did not contain an object core

What it means

`canonical_order` serializes an OrderAny to JSON, locates its variant payload, and expects an inner `core` object containing the order's shared fields. This internal error is thrown when the serialized JSON has no `core` object inside the variant payload — meaning the serde representation of the order does not match the expected internally-tagged shape. It is an invariant violation rather than user input validation.

Source

Thrown at crates/backtest/src/result.rs:522

    }
    anyhow::ensure!(
        object.get("returns_series").is_some_and(Value::is_array),
        "canonical returns series must be an array"
    );
    Ok(())
}

fn optional_nanos(value: Option<UnixNanos>) -> Value {
    value.map_or(Value::Null, |nanos| Value::String(nanos.to_string()))
}

fn canonical_order(order: &OrderAny) -> anyhow::Result<Value> {
    let mut value = serde_json::to_value(order)?;
    let payload = variant_payload_mut(&mut value)?;
    let core = payload
        .get_mut("core")
        .and_then(Value::as_object_mut)
        .ok_or_else(|| anyhow::anyhow!("serialized order did not contain an object core"))?;
    set_decimal(core, "avg_px", order.avg_px());
    set_decimal(core, "slippage", order.slippage());

    if let Some(events) = core.get_mut("events").and_then(Value::as_array_mut) {
        for (source, encoded) in order.events().into_iter().zip(events) {
            patch_order_event_decimals(source, encoded)?;
        }
    }
    set_decimal_if_present(payload, "limit_offset", order.limit_offset());
    set_decimal_if_present(payload, "trailing_offset", order.trailing_offset());
    canonicalize_value(&mut value)?;
    Ok(value)
}

fn canonical_fills(orders: &[OrderAny]) -> anyhow::Result<Vec<Value>> {
    let mut fills = Vec::new();

    for order in orders {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Regenerate/serialize the order with the matching library version so the variant payload contains a `core` object
  2. Check for version mismatch between the crate that constructed the order and the one canonicalizing it
  3. Inspect the serde representation (serde_json::to_value(order)) to confirm the expected tagged shape
  4. Avoid custom serialization wrappers around OrderAny before canonicalization

Example fix

// before (drifted serde shape)
{"order": {"limit": {"avg_px": 1.0, ...}}}          // no core
// after (expected shape)
{"order": {"limit": {"core": {"avg_px": "1.0", ...}}}}
Defensive patterns

Strategy: try-catch

Validate before calling

fn order_core_present(order: &OrderAny) -> anyhow::Result<bool> {
    let value = serde_json::to_value(order)?;
    Ok(value
        .get("order")
        .or_else(|| value.get("limit").or_else(|| value.get("market"))
            .map(|_| &value).unwrap_or(&value))
        .pointer("/core")
        .map_or(false, serde_json::Value::is_object))
}

Type guard

fn has_object_core(payload: &serde_json::Value) -> bool {
    payload.get("core").map_or(false, serde_json::Value::is_object)
}

Try / catch

let canonical = canonical_order(&order).map_err(|e| {
    if e.to_string().contains("did not contain an object core") {
        // log serde representation and crate versions for diagnosis
    }
    e
})?;

Prevention

When it happens

Trigger: Calling canonical_order (during canonical result document generation) with an OrderAny whose serde JSON lacks a `core` object in its variant payload — e.g. after a serde representation change of the order enum, a custom/foreign order variant, or tampered serialization.

Common situations: Mixing order types from a different nautilus version (serde format drift); a custom OrderAny payload that bypasses the standard order core; generated JSON wrapped or transformed by an intermediate layer that renamed `core`.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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