nautechsystems/nautilus_trader · error

failed to parse Lighter active order {} for acknowledged cre

Error message

failed to parse Lighter active order {} for acknowledged create

What it means

The single active order matched during reconciliation could not be converted into a Nautilus OrderStatusReport by parse_http_order_to_report (e.g. its instrument or price data cannot be mapped to a registered instrument). The adapter refuses to emit a create-acknowledgement from an unparseable venue order.

Source

Thrown at crates/adapters/lighter/src/websocket/dispatch.rs:1769

        .get_account_active_orders(&query)
        .await
        .context("failed to fetch Lighter active orders")?;

    let mut matches = active
        .orders
        .iter()
        .filter(|order| order.client_order_index == client_order_index && order.nonce == nonce);
    let Some(order) = matches.next() else {
        return Ok(None);
    };
    anyhow::ensure!(
        matches.next().is_none(),
        "ambiguous Lighter active-order lookup for client_order_index {client_order_index} and nonce {nonce}",
    );

    let report = parse_http_order_to_report(order, registry, account_id, clock.get_time_ns())
        .ok_or_else(|| {
            anyhow::anyhow!(
                "failed to parse Lighter active order {} for acknowledged create",
                order.order_index,
            )
        })?;
    let report = dispatch
        .translate_order_cloid(report)
        .with_client_order_id(client_order_id);
    Ok(Some(dispatch.preserve_pending_order_status(report)))
}

/// Look up a single order via the active and inactive HTTP endpoints, returning
/// the corresponding [`OrderStatusReport`] if found.
///
/// Resolution order: explicit `venue_order_id` > cached `venue_id_map` >
/// derived `client_order_index` from `dispatch.derive_client_order_index`.
/// The third path is active-order only. It makes `query_order` work between
/// submission and the venue's first `account_*` ack, while avoiding ambiguous
/// terminal history where Lighter can reuse client indexes.

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Ensure the instrument provider has loaded all markets before reconciliation (initialize instruments first).
  2. Log the raw order JSON and extend parse_http_order_to_report to handle the offending field values.
  3. Refresh/rebuild the instrument registry if markets changed on the venue.

Example fix

// before: reconcile before instruments are loaded
// after
let _ = ws.instruments_cache_ready().await; // wait for instrument provider initialization before lookup_active_order
Defensive patterns

Strategy: try-catch

Validate before calling

if registry.market_index(&instrument_id).is_none() { return Err("instrument not registered"); }

Try / catch

match result { Err(e) if e.to_string().contains("failed to parse Lighter active order") => { /* refresh instruments and retry */ }, other => other? }

Prevention

When it happens

Trigger: Reconciling an acknowledged create where the matching Lighter order's fields (instrument_id, prices, lot/tick mapping) fail to parse against the instrument registry — e.g. order references a market not in the registry or has NaN/zero fields the parser rejects.

Common situations: Instrument provider not fully loaded/initialized before reconciliation; venue order on a newly listed market missing from the local registry; stale instruments cache after venue changes.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


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