nautechsystems/nautilus_trader · error · anyhow::Error
invalid `tp_order_type`, was {other}
Error message
invalid `tp_order_type`, was {other} What it means
In `try_bracket`, the take-profit leg is constructed by matching on `tp_order_type`; only order types supported as a TP contingency (typically limit, stop-limit, and related) are handled. Any other variant reaches the catch-all arm and bails with this error, so the requested take-profit order type cannot form a valid bracket.
Source
Thrown at crates/common/src/factories/order.rs:1661
true, // reduce_only
quote_quantity,
None, // display_qty
emulation_trigger,
trigger_instrument_id,
tp_contingency_type,
tp_order_list_id,
tp_linked_order_ids,
tp_parent_order_id,
tp_exec_algorithm_id,
tp_exec_algorithm_params,
tp_exec_spawn_id,
tp_tags,
UUID4::new(),
ts_init,
)?;
OrderAny::TrailingStopLimit(order)
}
other => anyhow::bail!("invalid `tp_order_type`, was {other}"),
};
let sl_contingency_type = Some(contingency_type);
let sl_order_list_id = Some(order_list_id);
let sl_linked_order_ids = Some(vec![tp_client_order_id]);
let sl_parent_order_id = Some(entry_client_order_id);
let sl_order = match sl_order_type {
OrderType::StopMarket => OrderAny::StopMarket(StopMarketOrder::new_checked(
self.trader_id,
self.strategy_id,
instrument_id,
sl_client_order_id,
sl_tp_side,
quantity,
required(
sl_trigger_price,
"`sl_trigger_price` is required for a STOP_MARKET stop-loss",View on GitHub (pinned to 18893faf8b)
Solutions
- Use a supported take-profit order type (e.g. limit or stop-limit) for the TP leg.
- Validate tp_order_type against the supported set before calling bracket().
- If a trailing/stop TP is needed, build the orders manually (entry + separate contingent orders) instead of via bracket().
- Check the library version's bracket documentation for exactly which OrderType values are accepted for tp_order_type.
Example fix
// before let orders = factory.bracket(tp_order_type = OrderType::TrailingStopMarket, ...)?; // after let tp_order_type = OrderType::Limit; // supported TP leg let orders = factory.bracket(tp_order_type = tp_order_type, ...)?;
Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED_TP: &[OrderType] = &[
OrderType::Limit, OrderType::StopLimit,
];
if !SUPPORTED_TP.contains(&tp_order_type) {
return Err(anyhow::anyhow!(
"unsupported bracket tp_order_type: {tp_order_type:?}"
));
} Type guard
fn is_valid_bracket_tp(t: OrderType) -> bool {
matches!(t, OrderType::Limit | OrderType::StopLimit)
} Try / catch
match factory.bracket(tp_order_type = tp_order_type, ...) {
Ok(orders) => orders,
Err(e) if e.to_string().contains("invalid `tp_order_type`") => {
bail!("bracket TP type {tp_order_type:?} unsupported; use Limit/StopLimit")
}
Err(e) => return Err(e),
} Prevention
- Do not reuse stop-leg order type settings for the TP leg.
- Validate user-supplied TP order type from config before building the bracket.
- Cover the supported TP-type set with a unit test on the bracket factory.
When it happens
Trigger: Calling `factory.bracket(...)` with a `tp_order_type` that is not one of the supported take-profit variants — e.g. TRAILING_STOP_MARKET or a market/stop-market type where the factory expects limit-family types for the TP leg.
Common situations: Strategy configs where the TP type is user-supplied and unchecked; copying SL-type settings into the TP slot; library version changes adding order types that the bracket factory does not yet support for TP legs.
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/b9eb4564549d9d9f.
Report an issue: GitHub.