nautechsystems/nautilus_trader · error

order conversion must set a CLOID

Error message

order conversion must set a CLOID

What it means

When submitting orders over the Hyperliquid websocket, the adapter requires each built `HyperliquidExchangePlaceOrderRequest` to carry a `cloid` (client order ID) so it can cache the client_order_id↔cloid mapping for order tracking and cancels/modifies by CLOID. The conversion from a Nautilus order to an exchange request must always set `cloid`; a `None` means the conversion function skipped it, and downstream ID correlation would silently break, so the code panics.

Source

Thrown at crates/adapters/hyperliquid/src/execution.rs:2903

    staged_brackets: Arc<Mutex<StagedBracketState>>,
    builder: Option<crate::http::models::HyperliquidExchangeBuilderFee>,
    clock: &'static AtomicTime,
    task_spawner: &TaskSpawner,
) {
    let (orders, requests): (Vec<_>, Vec<_>) = children
        .into_iter()
        .map(|child| (child.order, child.request))
        .unzip();

    let denied_orders = orders.clone();
    let task_emitter = emitter.clone();
    let ws_client = ws_client.clone();
    let http_client = http_client.clone();
    let child_spawner = task_spawner.clone();

    if let Err(e) = task_spawner.spawn(async move {
        for (order, request) in orders.iter().zip(requests.iter()) {
            let cloid = request.cloid.expect("order conversion must set a CLOID");
            http_client.cache_client_order_id_cloid(order.client_order_id(), cloid);
            ws_client.cache_cloid_mapping(Ustr::from(&cloid.to_hex()), order.client_order_id());
            register_order_context_into(&dispatch_state, order);
            task_emitter.emit_order_submitted(order);
        }

        post_order_batch(
            "Bracket child batch",
            orders,
            requests,
            HyperliquidExchangeGrouping::Na,
            builder,
            &task_emitter,
            &ws_client,
            &http_client,
            dispatch_state,
            staged_brackets,
            clock,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Fix the order-to-request conversion so `cloid: Some(...)` is always populated (derive it from the order's client_order_id via `Cloid::from_client_order_id`).
  2. Ensure every submitted order has a client_order_id assigned before reaching the Hyperliquid execution client.
  3. In the submit loop, convert the expect into an error log + skip (or reject the order) so one malformed order doesn't kill the task.
  4. Add a test asserting every converted request has a Some(cloid) for each supported order type.

Example fix

// before
let request = HyperliquidExchangePlaceOrderRequest {
    // ... fields ...
    cloid: None, // or omitted
    ..Default::default()
};
// after
let cloid = Cloid::from_client_order_id(order.client_order_id());
let request = HyperliquidExchangePlaceOrderRequest {
    // ... fields ...
    cloid: Some(cloid),
    ..Default::default()
};
Defensive patterns

Strategy: validation

Validate before calling

let Some(cloid) = request.cloid else {
    tracing::error!(order_id = %order.client_order_id(), "request missing CLOID");
    continue; // or return an error rejecting the order
};

Prevention

When it happens

Trigger: Submitting a `SubmitOrder` whose conversion into `HyperliquidExchangePlaceOrderRequest` left `cloid: None` — e.g. the order lacks a client_order_id, or the converter was modified/extended (new order type) without assigning the CLOID; the panic then fires in the submit task when zipping orders with requests.

Common situations: Adding support for a new Hyperliquid order type or trigger/TPSL orders and the conversion path forgets `cloid`; orders created without client order IDs; a version change in the conversion helpers dropping the cloid assignment.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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