nautechsystems/nautilus_trader · error · PyValueError
Invalid BybitPositionIdx value: {int_val}
Error message
Invalid BybitPositionIdx value: {int_val} What it means
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.
Source
Thrown at crates/adapters/bybit/src/python/enums.rs:363
pub fn value(&self) -> i32 {
*self as i32
}
#[staticmethod]
#[must_use]
fn variants() -> Vec<String> {
Self::iter().map(|x| x.to_string()).collect()
}
#[classmethod]
#[pyo3(name = "from_str")]
fn py_from_str(_cls: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
if let Ok(int_val) = data.extract::<i32>() {
return match int_val {
0 => Ok(Self::OneWay),
1 => Ok(Self::BuyHedge),
2 => Ok(Self::SellHedge),
_ => Err(to_pyvalue_err(anyhow::anyhow!(
"Invalid BybitPositionIdx value: {int_val}"
))),
};
}
let data_str: String = data.str()?.extract()?;
Self::from_str(&data_str).map_err(to_pyvalue_err)
}
}
#[pymethods]
#[pyo3_stub_gen::derive::gen_stub_pymethods]
impl BybitMarginAction {
/// Margin actions for spot margin trading operations.
#[new]
fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
let t = Self::type_object(py);
Self::py_from_str(&t, value)View on GitHub (pinned to 18893faf8b)
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
Example fix
// before: mixing up mode and index encodings idx = BybitPositionIdx.from_str(3) // after idx = BybitPositionIdx.from_str(1) # BuyHedge
Defensive patterns
Strategy: type-guard
Validate before calling
if isinstance(v, int) and v not in (0, 1, 2):
raise ValueError(f'positionIdx must be 0, 1, or 2, got {v}') Type guard
def is_valid_position_idx(v) -> bool:
return v in (0, 1, 2) or str(v) in ('OneWay', 'BuyHedge', 'SellHedge') Try / catch
try:
idx = BybitPositionIdx.from_str(raw)
except ValueError as e:
log.warning('bad positionIdx %r', raw); idx = BybitPositionIdx.OneWay Prevention
- 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
When it happens
Trigger: 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.
Common situations: Using positionIdx values intended for another exchange; copy-pasting position-mode codes (0/3) into positionIdx; corrupted or fabricated test payloads.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Invalid BybitPositionMode value: {int_val}
- Invalid NodeState value
- Timedelta not supported for aggregation type: {:?}
- Invalid `ConnectionMode` value: {value}
- Unsupported SBE execution type: {et}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/29f7ba1bbdb86623.
Report an issue: GitHub.