nautechsystems/nautilus_trader · error · anyhow::Error

Reduce-only is not supported for Hyperliquid HIP-4 outcomes:

Error message

Reduce-only is not supported for Hyperliquid HIP-4 outcomes: {symbol}

What it means

HIP-4 outcome tokens are fully-collateralized side tokens with no margin or funding machinery, so reduce-only semantics do not apply. The adapter rejects any reduce-only order targeting an Outcome product with this error.

Source

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

    match order.order_type() {
        OrderType::Market
        | OrderType::Limit
        | OrderType::StopMarket
        | OrderType::StopLimit
        | OrderType::MarketIfTouched
        | OrderType::LimitIfTouched => {}
        _ => anyhow::bail!(
            "Unsupported order type for Hyperliquid: {:?}",
            order.order_type()
        ),
    }

    // HIP-4 outcomes are fully-collateralized side tokens with no margin,
    // funding, or trigger machinery. Reject features that don't apply.
    if product_type == HyperliquidProductType::Outcome {
        if order.is_reduce_only() {
            anyhow::bail!("Reduce-only is not supported for Hyperliquid HIP-4 outcomes: {symbol}");
        }

        if !matches!(order.order_type(), OrderType::Market | OrderType::Limit) {
            anyhow::bail!(
                "Trigger order types are not supported for Hyperliquid HIP-4 outcomes: \
                 {symbol} (received {:?})",
                order.order_type()
            );
        }
    }

    if matches!(
        order.order_type(),
        OrderType::StopMarket
            | OrderType::StopLimit
            | OrderType::MarketIfTouched
            | OrderType::LimitIfTouched
    ) && order.trigger_price().is_none()

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Set is_reduce_only to false for orders on HIP-4 outcome instruments.
  2. Skip reduce-only position-closing logic for outcome tokens and size the closing order explicitly instead.
  3. Branch on the instrument's product type before submission so perp-only features are not applied to outcomes.

Example fix

// before
let order = factory.limit(...).reduce_only();
exec_client.submit_order(&order).await?;
// after
let is_outcome = product_type == HyperliquidProductType::Outcome;
let order = factory.limit(...);
let order = if is_outcome { order } else { order.reduce_only() };
exec_client.submit_order(&order).await?;
Defensive patterns

Strategy: validation

Validate before calling

fn can_reduce_only(product_type: HyperliquidProductType) -> bool {
    product_type != HyperliquidProductType::Outcome
}

Prevention

When it happens

Trigger: Submitting an order with is_reduce_only() true where the instrument resolves to HyperliquidProductType::Outcome; e.g. reusing a close-position reduce-only flow for an outcome side token.

Common situations: Generic position-closing logic that always sets reduce_only, applied to HIP-4 outcome markets; strategies copied from perpetual markets and run against outcome tokens.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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