{"record":{"id":"c635bc5f2fcd4458","repo":"nautechsystems/nautilus_trader","slug":"tp-override-fields-require-take-profit-to-be-set","errorCode":null,"errorMessage":"TP override fields require 'take_profit' to be set","messagePattern":"TP override fields require 'take_profit' to be set","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/bybit/src/common/parse.rs","lineNumber":1864,"sourceCode":"        result.sl_order_type = Some(parse_tp_sl_order_type(s)?);\n    }\n\n    if let Some(s) = params.get_str(\"tpsl_mode\") {\n        result.tpsl_mode = Some(parse_tpsl_mode(s)?);\n    }\n\n    let has_tp_fields = result.tp_trigger_by.is_some()\n        || result.tp_order_type.is_some()\n        || result.tp_limit_price.is_some()\n        || result.tp_trigger_price.is_some();\n\n    let has_sl_fields = result.sl_trigger_by.is_some()\n        || result.sl_order_type.is_some()\n        || result.sl_limit_price.is_some()\n        || result.sl_trigger_price.is_some();\n\n    if result.take_profit.is_none() && has_tp_fields {\n        anyhow::bail!(\"TP override fields require 'take_profit' to be set\");\n    }\n\n    if result.stop_loss.is_none() && has_sl_fields {\n        anyhow::bail!(\"SL override fields require 'stop_loss' to be set\");\n    }\n\n    if result.tp_order_type == Some(BybitOrderType::Limit) && result.tp_limit_price.is_none() {\n        anyhow::bail!(\"'tp_order_type' is 'Limit' but 'tp_limit_price' was not provided\");\n    }\n\n    if result.sl_order_type == Some(BybitOrderType::Limit) && result.sl_limit_price.is_none() {\n        anyhow::bail!(\"'sl_order_type' is 'Limit' but 'sl_limit_price' was not provided\");\n    }\n\n    if result.tp_limit_price.is_some() && result.tp_order_type != Some(BybitOrderType::Limit) {\n        anyhow::bail!(\"'tp_limit_price' requires 'tp_order_type' to be 'Limit'\");\n    }\n","sourceCodeStart":1846,"sourceCodeEnd":1882,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/bybit/src/common/parse.rs#L1846-L1882","documentation":"After parsing, parse_bybit_tp_sl_params enforces that TP override fields (tp_trigger_by, tp_order_type, tp_limit_price, tp_trigger_price) may only be supplied when a take_profit price is also set. Supplying an override without the base take_profit raises this anyhow error (and symmetrically for SL overrides).","triggerScenarios":"Submitting an order with params containing e.g. tp_trigger_by='MarkPrice' or tp_order_type='Limit' but no take_profit key.","commonSituations":"Refining an existing TP order but forgetting to re-send the take_profit price; copy-pasting only the override block from an example; partial config merges dropping the take_profit key.","solutions":["Include take_profit in the params whenever you send any tp_* override field","Remove the orphaned tp_* override fields if you did not intend to set a take profit","Bundle the complete TP definition (take_profit plus overrides) together in one params map"],"exampleFix":"// before\nparams.insert(\"tp_order_type\", \"Limit\");\n// after\nparams.insert(\"take_profit\", \"30100.0\");\nparams.insert(\"tp_order_type\", \"Limit\");","handlingStrategy":"validation","validationCode":"tp_overrides = [k for k in params if k.startswith(\"tp_\")]\nif tp_overrides:\n    assert \"take_profit\" in params, \"tp_* overrides require take_profit\"\nsl_overrides = [k for k in params if k.startswith(\"sl_\")]\nif sl_overrides:\n    assert \"stop_loss\" in params, \"sl_* overrides require stop_loss\"","typeGuard":"fn tp_sl_params_complete(params: &Params) -> bool {\n    let has_tp_fields = params.keys().any(|k| k.starts_with(\"tp_\"));\n    let has_sl_fields = params.keys().any(|k| k.starts_with(\"sl_\"));\n    (!has_tp_fields || params.contains_key(\"take_profit\"))\n        && (!has_sl_fields || params.contains_key(\"stop_loss\"))\n}","tryCatchPattern":"if let Err(e) = parse_bybit_tp_sl_params(Some(&params)) {\n    log::error!(\"TP/SL params rejected: {e}\");\n    // resubmit with base price or drop the overrides\n}","preventionTips":["Always send take_profit/stop_loss together with their override fields","Build TP/SL param bundles via a single helper so base prices cannot be omitted","When editing an existing TP/SL, resend the complete set of fields"],"tags":["bybit","tpsl","missing-required-field","validation","order"],"backgroundTag":"missing-required-argument","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}