{"record":{"id":"fe3534ee6b49c99f","repo":"nautechsystems/nautilus_trader","slug":"invalid-probability-must-not-be-1-0-inverse-woul","errorCode":null,"errorMessage":"invalid probability: must not be 1.0 (inverse would be zero)","messagePattern":"invalid probability: must not be 1\\.0 \\(inverse would be zero\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/data/bet.rs","lineNumber":706,"sourceCode":"///\n/// # Errors\n///\n/// Returns an error if `probability` is zero.\npub fn check_probability_non_zero(probability: Decimal) -> anyhow::Result<()> {\n    if probability.is_zero() {\n        anyhow::bail!(\"invalid probability: must be non-zero\")\n    }\n    Ok(())\n}\n\n/// Checks that `probability` is invertible (not equal to 1.0).\n///\n/// # Errors\n///\n/// Returns an error if `probability` is 1.0.\npub fn check_probability_invertible(probability: Decimal) -> anyhow::Result<()> {\n    if probability == Decimal::ONE {\n        anyhow::bail!(\"invalid probability: must not be 1.0 (inverse would be zero)\")\n    }\n    Ok(())\n}\n\n/// Converts a probability and volume into a Bet.\n///\n/// For a BUY side, this creates a BACK bet; for SELL, a LAY bet.\n///\n/// # Errors\n///\n/// Returns an error if `probability` is zero or the conversion overflows.\npub fn probability_to_bet(\n    probability: Decimal,\n    volume: Decimal,\n    side: OrderSide,\n) -> anyhow::Result<Bet> {\n    check_probability_non_zero(probability)?;\n    let price = checked_div(Decimal::ONE, probability)?;","sourceCodeStart":688,"sourceCodeEnd":724,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/data/bet.rs#L688-L724","documentation":"check_probability_invertible validates that a probability is not exactly 1.0 before an inverse operation. The inverse probability is computed as 1 - probability; when probability is 1.0 the inverse is zero, which cannot be used (e.g. zero odds/volume in a derived Bet). The library refuses up-front instead of producing a degenerate value downstream.","triggerScenarios":"Calling inverse_probability_to_bet(probability, volume, side) or any code path that calls check_probability_invertible with probability == Decimal::ONE (exactly 1.0, not merely close to 1).","commonSituations":"Betting/trading code computing lay-side bets from a back probability of certainty; a data feed reporting 100% implied probability; a user passing a settled/known-outcome probability of 1.0 into bet construction.","solutions":["Pass a probability strictly less than 1.0; clamp values to just below 1 (e.g. Decimal::new(999999, 6)) if the source may report certainty.","Check the input before calling: if probability == Decimal::ONE, handle it as a special case (skip the inverse or use the complementary odds directly).","Verify the upstream data source; a 1.0 probability usually indicates a feed or unit-conversion bug (e.g. 100 instead of 1, or 100% not divided by 100)."],"exampleFix":"// before\nlet bet = inverse_probability_to_bet(Decimal::ONE, volume, side)?;\n// after\nanyhow::ensure!(probability < Decimal::ONE, \"probability must be < 1.0\");\nlet bet = inverse_probability_to_bet(probability, volume, side)?;","handlingStrategy":"validation","validationCode":"// Rust\nuse rust_decimal::Decimal;\nfn is_invertible_probability(p: Decimal) -> bool { p < Decimal::ONE && p >= Decimal::ZERO }\n// Python\n# def is_invertible_probability(p): return 0 <= p < 1","typeGuard":null,"tryCatchPattern":"// Rust\nmatch inverse_probability_to_bet(p, volume, side) {\n    Ok(bet) => bet,\n    Err(e) if e.to_string().contains(\"must not be 1.0\") => handle_certain_outcome(),\n    Err(e) => return Err(e),\n}","preventionTips":["Clamp probabilities to [0, 1 - epsilon] at ingestion boundaries.","Verify percentage-to-decimal conversion (100% -> 1.0 is still invalid for inversion).","Unit-test the certain-outcome edge case in any bet construction code."],"tags":["decimal","validation","betting"],"backgroundTag":"invalid-argument-value","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}