nautechsystems/nautilus_trader · error · anyhow::Error

Conditional order missing tpsl indicator

Error message

Conditional order missing tpsl indicator

What it means

validate_conditional_order_params requires a tpsl indicator because Hyperliquid trigger orders must declare whether they are a take-profit (Tp) or stop-loss (Sl). A None tpsl cannot be encoded into the request, so the validator rejects it. The enum type guarantees a valid value; only presence is checked.

Source

Thrown at crates/adapters/hyperliquid/src/common/parse.rs:894

    }
}

/// Validates conditional order parameters from WebSocket data.
///
/// # Returns
///
/// `Ok(())` if parameters are valid, `Err` with description otherwise.
pub fn validate_conditional_order_params(
    trigger_px: Option<&str>,
    tpsl: Option<&HyperliquidTpSl>,
    is_market: Option<bool>,
) -> anyhow::Result<()> {
    if trigger_px.is_none() {
        anyhow::bail!("Conditional order missing trigger price");
    }

    if tpsl.is_none() {
        anyhow::bail!("Conditional order missing tpsl indicator");
    }

    // No need to validate tpsl value - the enum type guarantees it's either Tp or Sl

    if is_market.is_none() {
        anyhow::bail!("Conditional order missing is_market flag");
    }

    Ok(())
}

/// Parses trigger price from string to Decimal.
///
/// # Returns
///
/// Parsed Decimal value or error.
pub fn parse_trigger_price(trigger_px: &str) -> anyhow::Result<Decimal> {
    Decimal::from_str_exact(trigger_px)

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Set the tpsl field to HyperliquidTpSl::Tp or HyperliquidTpSl::Sl depending on the order's intent.
  2. Derive tpsl automatically from order side and trigger direction before validation.
  3. If no TP/SL semantics are intended, use the non-TPSL trigger order construction path that doesn't call this validator.

Example fix

// before
validate_conditional_order_params(Some(trigger_px), None, Some(false))?;
// after
validate_conditional_order_params(Some(trigger_px), Some(&HyperliquidTpSl::Sl), Some(false))?;
Defensive patterns

Strategy: validation

Validate before calling

let tpsl = tpsl.or(if is_take_profit { Some(HyperliquidTpSl::Tp) } else { Some(HyperliquidTpSl::Sl) });
validate_conditional_order_params(trigger_px, Some(&tpsl), is_market)?;

Prevention

When it happens

Trigger: Calling validate_conditional_order_params with tpsl: None — e.g. building a trigger order request where the TpSl discriminator was not set from user config or parsed params.

Common situations: Configuring stop-loss/take-profit orders where only the trigger price was supplied; generic order-building code reused for both plain trigger and TPSL orders, omitting the tpsl field for the latter.

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/bba724d60f141cad. Report an issue: GitHub.