nautechsystems/nautilus_trader · error · anyhow::Error

invalid `sl_order_type`, was {other}

Error message

invalid `sl_order_type`, was {other}

What it means

This error is thrown by the bracket order factory when building a bracket (entry + stop-loss + take-profit) order and the supplied `sl_order_type` is not one of the supported stop-loss order types (stop-market or trailing-stop-market). The factory matches on the order type enum and falls through to this bail for any other variant. It means the caller passed an entry-style or unsupported order type where only specific stop-loss types are valid.

Source

Thrown at crates/common/src/factories/order.rs:1741

                    true, // reduce_only
                    quote_quantity,
                    None, // display_qty
                    emulation_trigger,
                    trigger_instrument_id,
                    sl_contingency_type,
                    sl_order_list_id,
                    sl_linked_order_ids,
                    sl_parent_order_id,
                    sl_exec_algorithm_id,
                    sl_exec_algorithm_params,
                    sl_exec_spawn_id,
                    sl_tags,
                    UUID4::new(),
                    ts_init,
                )?;
                OrderAny::TrailingStopMarket(order)
            }
            other => anyhow::bail!("invalid `sl_order_type`, was {other}"),
        };

        Ok(vec![entry_order, sl_order, tp_order])
    }
}

fn required<T>(value: Option<T>, message: &'static str) -> anyhow::Result<T> {
    value.ok_or_else(|| anyhow::anyhow!(message))
}

#[cfg(test)]
pub mod tests {
    use std::{cell::RefCell, rc::Rc};

    use indexmap::IndexMap;
    use nautilus_core::UnixNanos;
    use nautilus_model::{
        enums::{

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Pass `OrderType::StopMarket` or `OrderType::TrailingStopMarket` as `sl_order_type`
  2. If a stop-limit is needed, construct the stop-loss order separately instead of via `bracket`
  3. Check config parsing that produces `sl_order_type` and validate it against the supported set before calling `bracket`

Example fix

// before
factory.bracket(..., entry_order_type, sl_order_type = order_type, ...)
// after
let sl_order_type = OrderType::StopMarket; // or TrailingStopMarket
factory.bracket(..., entry_order_type, sl_order_type, ...)
Defensive patterns

Strategy: validation

Validate before calling

fn validate_sl_order_type(t: OrderType) -> Result<(), String> {
    match t {
        OrderType::StopMarket | OrderType::TrailingStopMarket => Ok(()),
        other => Err(format!("sl_order_type must be StopMarket/TrailingStopMarket, was {other:?}")),
    }
}

Try / catch

let orders = match factory.bracket(...) {
    Ok(o) => o,
    Err(e) if e.to_string().contains("invalid `sl_order_type`") => {
        tracing::error!("bracket rejected sl_order_type: {e}");
        return Err(e);
    }
    Err(e) => return Err(e),
};

Prevention

When it happens

Trigger: Calling `OrderFactory::bracket(...)` (or `try_bracket`) with `sl_order_type` set to e.g. `OrderType::Limit`, `Market`, `StopLimit`, or any variant other than `StopMarket`/`TrailingStopMarket`. Typically caused by reusing the entry order type for the stop-loss parameter or misordering arguments.

Common situations: Config-driven strategies where the stop-loss order type is read from a config/CLI string and mapped incorrectly; code migrated from another API where bracket helpers accepted arbitrary stop types; typos passing the entry `OrderType` instead of the SL type.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — 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/e8c3913aa7bc89b7. Report an issue: GitHub.