{"record":{"id":"29f7ba1bbdb86623","repo":"nautechsystems/nautilus_trader","slug":"invalid-bybitpositionidx-value-int-val","errorCode":null,"errorMessage":"Invalid BybitPositionIdx value: {int_val}","messagePattern":"Invalid BybitPositionIdx value: (.+?)","errorType":"validation","errorClass":"PyValueError","httpStatus":null,"severity":"error","filePath":"crates/adapters/bybit/src/python/enums.rs","lineNumber":363,"sourceCode":"    pub fn value(&self) -> i32 {\n        *self as i32\n    }\n\n    #[staticmethod]\n    #[must_use]\n    fn variants() -> Vec<String> {\n        Self::iter().map(|x| x.to_string()).collect()\n    }\n\n    #[classmethod]\n    #[pyo3(name = \"from_str\")]\n    fn py_from_str(_cls: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {\n        if let Ok(int_val) = data.extract::<i32>() {\n            return match int_val {\n                0 => Ok(Self::OneWay),\n                1 => Ok(Self::BuyHedge),\n                2 => Ok(Self::SellHedge),\n                _ => Err(to_pyvalue_err(anyhow::anyhow!(\n                    \"Invalid BybitPositionIdx value: {int_val}\"\n                ))),\n            };\n        }\n\n        let data_str: String = data.str()?.extract()?;\n        Self::from_str(&data_str).map_err(to_pyvalue_err)\n    }\n}\n\n#[pymethods]\n#[pyo3_stub_gen::derive::gen_stub_pymethods]\nimpl BybitMarginAction {\n    /// Margin actions for spot margin trading operations.\n    #[new]\n    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {\n        let t = Self::type_object(py);\n        Self::py_from_str(&t, value)","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/bybit/src/python/enums.rs#L345-L381","documentation":"The Python-side BybitPositionIdx.from_str was given an integer other than 0, 1, or 2; those are the only Bybit position-index modes (one-way, buy hedge, sell hedge), so any other integer is rejected with ValueError.","triggerScenarios":"Deserializing a `positionIdx` value from a Bybit payload that is outside {0,1,2}, or passing a bad string/number to BybitPositionIdx.from_str in Python.","commonSituations":"Using positionIdx values intended for another exchange; copy-pasting position-mode codes (0/3) into positionIdx; corrupted or fabricated test payloads.","solutions":["Use 0 for one-way mode, 1 for hedge-mode buy side, 2 for hedge-mode sell side","Pass exact variant-name strings: 'OneWay', 'BuyHedge', 'SellHedge'","Verify hedge vs one-way mode on the Bybit account matches the positionIdx being sent"],"exampleFix":"// before: mixing up mode and index encodings\nidx = BybitPositionIdx.from_str(3)\n// after\nidx = BybitPositionIdx.from_str(1)  # BuyHedge","handlingStrategy":"type-guard","validationCode":"if isinstance(v, int) and v not in (0, 1, 2):\n    raise ValueError(f'positionIdx must be 0, 1, or 2, got {v}')","typeGuard":"def is_valid_position_idx(v) -> bool:\n    return v in (0, 1, 2) or str(v) in ('OneWay', 'BuyHedge', 'SellHedge')","tryCatchPattern":"try:\n    idx = BybitPositionIdx.from_str(raw)\nexcept ValueError as e:\n    log.warning('bad positionIdx %r', raw); idx = BybitPositionIdx.OneWay","preventionTips":["Don't conflate position-mode codes (0/3) with positionIdx codes (0/1/2)","Match positionIdx to the account's actual margin mode","Validate payloads before feeding enum constructors"],"tags":["rust","python","bybit","enum","position-index"],"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"}