{"record":{"id":"db720bce7dba5d1d","repo":"nautechsystems/nautilus_trader","slug":"invalid-bybit-tp-sl-order-type-s-expected-ma","errorCode":null,"errorMessage":"invalid Bybit TP/SL order type: '{s}', expected Market or Limit","messagePattern":"invalid Bybit TP/SL order type: '(.+?)', expected Market or Limit","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/bybit/src/common/parse.rs","lineNumber":1969,"sourceCode":"    Ok(result)\n}\n\npub(crate) fn parse_trigger_type(s: &str) -> anyhow::Result<BybitTriggerType> {\n    match s {\n        \"LastPrice\" => Ok(BybitTriggerType::LastPrice),\n        \"MarkPrice\" => Ok(BybitTriggerType::MarkPrice),\n        \"IndexPrice\" => Ok(BybitTriggerType::IndexPrice),\n        _ => anyhow::bail!(\n            \"invalid Bybit trigger type: '{s}', expected LastPrice, MarkPrice, or IndexPrice\"\n        ),\n    }\n}\n\npub(crate) fn parse_tp_sl_order_type(s: &str) -> anyhow::Result<BybitOrderType> {\n    match s {\n        \"Market\" => Ok(BybitOrderType::Market),\n        \"Limit\" => Ok(BybitOrderType::Limit),\n        _ => anyhow::bail!(\"invalid Bybit TP/SL order type: '{s}', expected Market or Limit\"),\n    }\n}\n\n// A plain `serde_json` deserialize would accept unknown strings: `BybitTpSlMode` carries a\n// `#[serde(other)] Unknown` variant, so garbage would silently map to `Unknown`.\npub(crate) fn parse_tpsl_mode(s: &str) -> anyhow::Result<BybitTpSlMode> {\n    match s {\n        \"Full\" => Ok(BybitTpSlMode::Full),\n        \"Partial\" => Ok(BybitTpSlMode::Partial),\n        _ => anyhow::bail!(\"invalid Bybit TP/SL mode: '{s}', expected Full or Partial\"),\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use nautilus_model::{\n        data::BarSpecification,\n        enums::{AggregationSource, BarAggregation, PositionSide, PriceType},","sourceCodeStart":1951,"sourceCodeEnd":1987,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/bybit/src/common/parse.rs#L1951-L1987","documentation":"When parsing Bybit TP/SL parameters, the adapter maps the order type attached to TP/SL orders to BybitOrderType. Only \"Market\" and \"Limit\" are defined by Bybit for TP/SL orders; any other string is rejected explicitly instead of falling through serde's lenient deserialization.","triggerScenarios":"parse_bybit_tp_sl_params receives a payload where the TP/SL order type field (e.g. orderType in the TPSL response) is not exactly \"Market\" or \"Limit\" — typos, lowercase 'market', or an exchange-side new value.","commonSituations":"Mock/test fixtures with wrong casing; a newer Bybit API adding an order type the adapter doesn't know; manually constructed JSON used in integration testing.","solutions":["Inspect the raw response's orderType field and correct it to \"Market\" or \"Limit\"","Update the adapter/dependency to a version supporting the new order type","Fix fixture or mock data casing to match Bybit's exact strings"],"exampleFix":"// before\nparse_tp_sl_order_type(\"market\")? // rejected\n// after\nparse_tp_sl_order_type(\"Market\")?","handlingStrategy":"validation","validationCode":"fn is_valid_tpsl_order_type(s: &str) -> bool { matches!(s, \"Market\" | \"Limit\") }","typeGuard":"fn valid_order_type(s: &str) -> Option<BybitOrderType> {\n    match s { \"Market\" => Some(BybitOrderType::Market), \"Limit\" => Some(BybitOrderType::Limit), _ => None }\n}","tryCatchPattern":"let ot = parse_tp_sl_order_type(raw).unwrap_or(BybitOrderType::Market); // or surface the error","preventionTips":["Only construct TP/SL payloads from the adapter's typed enums","Fix fixtures to exact Bybit strings (\"Market\"/\"Limit\")","Track Bybit API changelogs for new order types"],"tags":["bybit","parsing","enum-validation","tpsl"],"backgroundTag":"invalid-enum-value","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"}