nautechsystems/nautilus_trader · error
'sl_order_type' is 'Limit' but 'sl_limit_price' was not prov
Error message
'sl_order_type' is 'Limit' but 'sl_limit_price' was not provided
What it means
Cross-field validation in parse_bybit_tp_sl_params: sl_order_type was set to Limit but no sl_limit_price accompanies it, so a stop-loss limit order would lack its limit price. The params are rejected as inconsistent.
Source
Thrown at crates/adapters/bybit/src/common/parse.rs:1876
let has_sl_fields = result.sl_trigger_by.is_some()
|| result.sl_order_type.is_some()
|| result.sl_limit_price.is_some()
|| result.sl_trigger_price.is_some();
if result.take_profit.is_none() && has_tp_fields {
anyhow::bail!("TP override fields require 'take_profit' to be set");
}
if result.stop_loss.is_none() && has_sl_fields {
anyhow::bail!("SL override fields require 'stop_loss' to be set");
}
if result.tp_order_type == Some(BybitOrderType::Limit) && result.tp_limit_price.is_none() {
anyhow::bail!("'tp_order_type' is 'Limit' but 'tp_limit_price' was not provided");
}
if result.sl_order_type == Some(BybitOrderType::Limit) && result.sl_limit_price.is_none() {
anyhow::bail!("'sl_order_type' is 'Limit' but 'sl_limit_price' was not provided");
}
if result.tp_limit_price.is_some() && result.tp_order_type != Some(BybitOrderType::Limit) {
anyhow::bail!("'tp_limit_price' requires 'tp_order_type' to be 'Limit'");
}
if result.sl_limit_price.is_some() && result.sl_order_type != Some(BybitOrderType::Limit) {
anyhow::bail!("'sl_limit_price' requires 'sl_order_type' to be 'Limit'");
}
result.close_on_trigger = params.get_bool("close_on_trigger");
if let Some(value) = params.get("order_iv") {
match get_price_str(params, "order_iv") {
Some(s) => result.order_iv = Some(s),
None => {
anyhow::bail!("invalid type for 'order_iv': {value}, expected string or number")
}View on GitHub (pinned to 18893faf8b)
Solutions
- Provide 'sl_limit_price' in params
- Set 'sl_order_type' to "Market" if no limit price is intended
Example fix
// before
params.set("sl_order_type", "Limit");
// after
params.set("sl_order_type", "Limit");
params.set("sl_limit_price", "39500"); Defensive patterns
Strategy: validation
Validate before calling
fn validate_sl_limit(params: &Params) -> Result<(), String> {
if params.get_str("sl_order_type") == Some("Limit") && params.get("sl_limit_price").is_none() {
return Err("sl_order_type Limit requires sl_limit_price".into());
}
Ok(())
} Type guard
fn is_limit_sl_missing_price(params: &Params) -> bool {
params.get_str("sl_order_type") == Some("Limit")
&& params.get("sl_limit_price").is_none()
} Try / catch
match parse_bybit_tp_sl_params(¶ms) {
Ok(p) => submit(p),
Err(e) if e.to_string().contains("'sl_limit_price' was not provided") => {
log::warn("Limit SL without price; add sl_limit_price or switch to Market");
}
Err(e) => return Err(e),
} Prevention
- Pair sl_order_type with sl_limit_price at construction time
- Default SL order type to Market when no limit price is configured
- Validate SL params in tests for every order-type variant
When it happens
Trigger: Setting params 'sl_order_type' = "Limit" without 'sl_limit_price'.
Common situations: Configuring a limit stop-loss after switching from market; deserialized params where sl_limit_price was lost.
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
- SL override fields require 'stop_loss' to be set
- 'tp_order_type' is 'Limit' but 'tp_limit_price' was not prov
- 'sl_limit_price' requires 'sl_order_type' to be 'Limit'
- invalid 'stop_loss' price: '{s}', expected a non-negative va
- 'tp_limit_price' requires 'tp_order_type' to be 'Limit'
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/32e0b8348d414ed6.
Report an issue: GitHub.