{"record":{"id":"f9ad1646f0ee57ff","repo":"nautechsystems/nautilus_trader","slug":"invalid-type-for-position-idx-value-expected","errorCode":null,"errorMessage":"invalid type for 'position_idx': {value}, expected integer","messagePattern":"invalid type for 'position_idx': (.+?), expected integer","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/bybit/src/common/parse.rs","lineNumber":1914,"sourceCode":"    }\n\n    if let Some(value) = params.get(\"mmp\") {\n        match value.as_bool() {\n            Some(b) => result.mmp = Some(b),\n            None => anyhow::bail!(\"invalid type for 'mmp': {value}, expected bool\"),\n        }\n    }\n\n    if let Some(value) = params.get(\"smp_type\") {\n        let smp_type = value.as_str().ok_or_else(|| {\n            anyhow::anyhow!(\"invalid type for 'smp_type': {value}, expected string\")\n        })?;\n        result.smp_type = Some(parse_smp_type(smp_type)?);\n    }\n\n    if let Some(value) = params.get(\"position_idx\") {\n        let idx = value.as_i64().ok_or_else(|| {\n            anyhow::anyhow!(\"invalid type for 'position_idx': {value}, expected integer\")\n        })?;\n        result.position_idx = Some(match idx {\n            0 => BybitPositionIdx::OneWay,\n            1 => BybitPositionIdx::BuyHedge,\n            2 => BybitPositionIdx::SellHedge,\n            _ => anyhow::bail!(\"invalid 'position_idx': {idx}, expected 0, 1, or 2\"),\n        });\n    }\n\n    let has_bbo_side_type = params.get(\"bbo_side_type\").is_some();\n    let has_bbo_level = params.get(\"bbo_level\").is_some();\n\n    if has_bbo_side_type != has_bbo_level {\n        anyhow::bail!(\"'bbo_side_type' and 'bbo_level' must be provided together\");\n    }\n\n    if let Some(value) = params.get(\"bbo_side_type\") {\n        let side_type = value.as_str().ok_or_else(|| {","sourceCodeStart":1896,"sourceCodeEnd":1932,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/bybit/src/common/parse.rs#L1896-L1932","documentation":"parse_bybit_tp_sl_params reads the optional 'position_idx' key and requires it to be an integer that maps to a Bybit position index mode. A non-integer value cannot be mapped to OneWay/BuyHedge/SellHedge, so the parser bails with the offending value interpolated.","triggerScenarios":"Setting params[\"position_idx\"] to a string like \"1\", a float, or any non-integer JSON value when building Bybit TP/SL params.","commonSituations":"Config files quoting the number (position_idx: \"1\"), or generic JSON configs where the field was not typed as a number.","solutions":["Pass position_idx as an integer 0, 1, or 2","Unquote the value in the config so it parses as a number","Validate the key type before calling parse_bybit_tp_sl_params"],"exampleFix":"// before\nlet params = serde_json::json!({\"position_idx\": \"1\"});\n// after\nlet params = serde_json::json!({\"position_idx\": 1});","handlingStrategy":"validation","validationCode":"if let Some(v) = params.get(\"position_idx\") {\n    assert!(v.is_i64(), \"position_idx must be an integer, got {v}\");\n}","typeGuard":"fn as_i64_param(v: &serde_json::Value) -> Option<i64> {\n    v.as_i64()\n}","tryCatchPattern":"let result = parse_bybit_tp_sl_params(&params)\n    .map_err(|e| e.context(\"position_idx must be an integer in TP/SL params\"))?;","preventionTips":["Avoid quoting numeric values in configs","Keep position_idx as a typed integer in your domain model","Validate the whole params map once at config load time"],"tags":["bybit","parsing","type-mismatch"],"backgroundTag":"type-mismatch","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"}