nautechsystems/nautilus_trader · info
fixed precision tick scheme is valid
Error message
fixed precision tick scheme is valid
What it means
Panic site inside the FIXED_PRECISION_TICK_SCHEMES static, which builds one FixedTickScheme per precision 0..=FIXED_PRECISION using tick = 10^-precision. Each value is positive and finite, so `FixedTickScheme::new` must succeed and this expect documents that invariant. A panic here would indicate the precision constant or constructor validation has been corrupted by a code change.
Source
Thrown at crates/model/src/instruments/tick_scheme.rs:209
(30_000_000.0, f64::INFINITY, 10_000.0),
],
4,
10_000,
)
.expect("TOPIX100 tick scheme tiers are valid by construction")
});
static FIXED_TICK_SCHEME: LazyLock<FixedTickScheme> =
LazyLock::new(|| FixedTickScheme::new(1.0).expect("fixed tick scheme is valid"));
static CRYPTO_0_01_TICK_SCHEME: LazyLock<FixedTickScheme> =
LazyLock::new(|| FixedTickScheme::new(0.01).expect("crypto tick scheme is valid"));
static FIXED_PRECISION_TICK_SCHEMES: LazyLock<Vec<FixedTickScheme>> = LazyLock::new(|| {
(0..=FIXED_PRECISION)
.map(|precision| {
let tick = 10_f64.powi(-i32::from(precision));
FixedTickScheme::new(tick).expect("fixed precision tick scheme is valid")
})
.collect()
});
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct FixedTickScheme {
tick: f64,
}
impl Eq for FixedTickScheme {}
impl FixedTickScheme {
/// Creates a new [`FixedTickScheme`] with the given tick size.
///
/// # Errors
///
/// Returns an error if `tick` is not finite or not positive.
pub fn new(tick: f64) -> Result<Self, TickSchemeError> {View on GitHub (pinned to 18893faf8b)
Solutions
- Check FIXED_PRECISION — if it exceeds f64's usable exponent range, 10^-p becomes 0.0 and fails validation; cap it below ~308 and within meaningful price precision.
- Review FixedTickScheme::new for epsilon-based rejection of small ticks.
- Run the tick scheme tests after any change to these constants.
- No caller-side mitigation; the statics must remain valid by construction.
Example fix
// before const FIXED_PRECISION: u8 = 250; // 10^-250 underflows toward 0 // after const FIXED_PRECISION: u8 = 16; // safe, meaningful price precision
Defensive patterns
Strategy: validation
Validate before calling
// Library-internal static; if you maintain this code, ensure: assert!(FIXED_PRECISION <= 16, "precision must keep 10^-p representable");
Prevention
- Cap FIXED_PRECISION well below f64 underflow range.
- Test the generated statics for all precisions after changing constants.
- Don't tighten FixedTickScheme::new validation without auditing all static call sites.
When it happens
Trigger: Untriggerable normally; would fire on first access to FIXED_PRECISION_TICK_SCHEMES if FIXED_PRECISION were set so large that 10^-precision underflows to 0.0, or if the constructor's validation changed to reject tiny ticks.
Common situations: Encountered only by library developers after raising FIXED_PRECISION (making ticks denormal/zero) or tightening FixedTickScheme::new's checks; end users see it as a panic during static init on first use.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- fixed tick scheme is valid
- crypto tick scheme is valid
- Close command should not be drained
- Flush command should not be drained
- Order invariant violated: first event must be OrderInitializ
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/f7b52940f0a1bb00.
Report an issue: GitHub.