nautechsystems/nautilus_trader · error
invalid probability: must not be 1.0 (inverse would be zero)
Error message
invalid probability: must not be 1.0 (inverse would be zero)
What it means
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.
Source
Thrown at crates/model/src/data/bet.rs:706
///
/// # Errors
///
/// Returns an error if `probability` is zero.
pub fn check_probability_non_zero(probability: Decimal) -> anyhow::Result<()> {
if probability.is_zero() {
anyhow::bail!("invalid probability: must be non-zero")
}
Ok(())
}
/// Checks that `probability` is invertible (not equal to 1.0).
///
/// # Errors
///
/// Returns an error if `probability` is 1.0.
pub fn check_probability_invertible(probability: Decimal) -> anyhow::Result<()> {
if probability == Decimal::ONE {
anyhow::bail!("invalid probability: must not be 1.0 (inverse would be zero)")
}
Ok(())
}
/// Converts a probability and volume into a Bet.
///
/// For a BUY side, this creates a BACK bet; for SELL, a LAY bet.
///
/// # Errors
///
/// Returns an error if `probability` is zero or the conversion overflows.
pub fn probability_to_bet(
probability: Decimal,
volume: Decimal,
side: OrderSide,
) -> anyhow::Result<Bet> {
check_probability_non_zero(probability)?;
let price = checked_div(Decimal::ONE, probability)?;View on GitHub (pinned to 18893faf8b)
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).
Example fix
// before let bet = inverse_probability_to_bet(Decimal::ONE, volume, side)?; // after anyhow::ensure!(probability < Decimal::ONE, "probability must be < 1.0"); let bet = inverse_probability_to_bet(probability, volume, side)?;
Defensive patterns
Strategy: validation
Validate before calling
// Rust
use rust_decimal::Decimal;
fn is_invertible_probability(p: Decimal) -> bool { p < Decimal::ONE && p >= Decimal::ZERO }
// Python
# def is_invertible_probability(p): return 0 <= p < 1 Try / catch
// Rust
match inverse_probability_to_bet(p, volume, side) {
Ok(bet) => bet,
Err(e) if e.to_string().contains("must not be 1.0") => handle_certain_outcome(),
Err(e) => return Err(e),
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Price must be greater than 1.0 for lay liability calculation
- invalid OrderSide: must be Buy or Sell, was {side}
- {e}
- Polymarket market BUY amount {} pUSD truncates to zero at {L
- Liability-based betting is only applicable for Lay side.
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/fe3534ee6b49c99f.
Report an issue: GitHub.