nautechsystems/nautilus_trader · error

precision exceeded i8 range

Error message

precision exceeded i8 range

What it means

`decode_price_increment` converts a Databento price-increment raw value into a `Price`. The `precision: u8` parameter must fit in `i8` because it is negated into the price exponent; the `.expect` panics when precision exceeds 127. This can only happen with absurd precision values not produced by any real instrument definition.

Source

Thrown at crates/adapters/databento/src/decode/primitives.rs:301

    }
    9 - trailing
}

/// Decodes a minimum price increment from the given value, expressed in units of 1e-9.
///
/// The precision is derived from the actual tick value to avoid truncation of
/// fractional tick sizes (e.g., treasury futures with 1/256 or 1/32 ticks).
/// The derived precision is floored at `precision` (typically the currency precision).
///
/// # Panics
///
/// Panics if `precision` exceeds the supported `Price` precision.
#[inline(always)]
#[must_use]
pub fn decode_price_increment(value: i64, precision: u8) -> Price {
    match value {
        0 | i64::MAX => {
            let exponent = i8::try_from(precision).expect("precision exceeded i8 range");
            Price::from_mantissa_exponent(1, -exponent, precision)
        }
        _ => {
            let derived = precision_from_raw(value).max(precision);
            Price::from_raw(decode_raw_price_i64(value), derived)
        }
    }
}

/// Decodes a quantity from the given value, expressed in standard whole-number units.
#[inline(always)]
#[must_use]
pub fn decode_quantity(value: u64) -> Quantity {
    quantity_from_whole(value)
}

/// Decodes a quantity from the given optional value, where `i64::MAX` indicates missing data.
///

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Validate the instrument definition's precision before decoding (clamp or reject precision > 127).
  2. Check that the tick size / denominator conversion feeding `precision` is correct for the dataset.
  3. If decoding third-party definitions, sanitize: use `precision.min(127)` or return a decode error instead of panicking.

Example fix

// before
let price = decode_price_increment(raw_tick, precision_u8);
// after
assert!(precision_u8 <= i8::MAX as u8, "unsupported precision {precision_u8}");
let price = decode_price_increment(raw_tick, precision_u8);
Defensive patterns

Strategy: validation

Validate before calling

if precision_u8 > i8::MAX as u8 {
    return Err(format!("unsupported precision {precision_u8}"));
}
let price = decode_price_increment(raw_tick, precision_u8);

Type guard

fn precision_ok(p: u8) -> bool { p <= i8::MAX as u8 }

Prevention

When it happens

Trigger: Calling `decode_price_increment` (directly or via `decode_currency_pair`/`decode_equity`/`decode_futures_contract`/etc.) with a precision greater than 127, typically from a raw instrument definition whose `raw_tick`/denominator math overflowed or was computed incorrectly.

Common situations: Custom/incorrect Symbology or instrument-definition data from Databento, a hand-rolled decoder passing raw exponent bytes as precision, or a regression in `precision_from_raw` producing garbage values.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/20c5e467d45840c7. Report an issue: GitHub.