{"record":{"id":"3a569001c34a8484","repo":"nautechsystems/nautilus_trader","slug":"failed-to-scale-continuous-future-adjustment-to-fi","errorCode":null,"errorMessage":"Failed to scale continuous-future adjustment to fixed precision","messagePattern":"Failed to scale continuous-future adjustment to fixed precision","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/data/src/aggregation.rs","lineNumber":228,"sourceCode":"    /// # Panics\n    ///\n    /// Panics if scaling the spread `adjustment` to the fixed-point representation overflows.\n    pub fn set_adjustment(&mut self, adjustment: Decimal, mode: ContinuousFutureAdjustmentType) {\n        if mode.is_ratio() {\n            self.adjustment_is_ratio = true;\n            self.adjustment_ratio = adjustment.to_f64().unwrap_or(1.0);\n            self.adjustment_active = adjustment != Decimal::ONE;\n            return;\n        }\n\n        // Spread mode: scale the Decimal offset to FIXED_PRECISION once so the hot path\n        // can add it straight onto `price.raw`. Signed PriceRaw supports negatives, so\n        // backward-spread offsets that push prices below zero remain representable.\n        self.adjustment_is_ratio = false;\n        let exponent = -(adjustment.scale() as i8);\n        let raw_i128 =\n            mantissa_exponent_to_fixed_i128(adjustment.mantissa(), exponent, FIXED_PRECISION)\n                .expect(\"Failed to scale continuous-future adjustment to fixed precision\");\n\n        #[allow(\n            clippy::useless_conversion,\n            reason = \"i128 to PriceRaw is real when not high-precision\"\n        )]\n        let raw: PriceRaw = raw_i128\n            .try_into()\n            .expect(\"Continuous-future adjustment exceeds PriceRaw range\");\n\n        self.adjustment_raw = raw;\n        self.adjustment_active = self.adjustment_raw != 0;\n    }\n\n    fn apply_adjustment_to_price(&self, price: Price) -> Price {\n        if !self.adjustment_active {\n            return price;\n        }\n","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/data/src/aggregation.rs#L210-L246","documentation":"`BarBuilder::set_adjustment` converts a continuous-future adjustment `Price` from its own mantissa/scale into the builder's fixed `FIXED_PRECISION` via `mantissa_exponent_to_fixed_i128`. If the rescale would lose precision or overflow the i128 intermediate, the helper returns None and this `.expect` panics.","triggerScenarios":"Calling `set_adjustment` with a Price whose scale is finer than FIXED_PRECISION (e.g. an 11+ decimal-place price when fixed precision is 9) or whose mantissa is so large that scaling up overflows i128.","commonSituations":"Configuring spread adjustment factors parsed from CSV/JSON with unusual precision; instruments quoted with more decimals than the platform's fixed precision; hand-built test prices with extreme exponents.","solutions":["Round/quantize the adjustment Price to FIXED_PRECISION before passing it to `set_adjustment`","Verify the adjustment mantissa comes from the instrument's price precision, not raw float parsing","Clamp or re-scale the adjustment value at the data-provider boundary","If larger precision is genuinely needed, this is a platform limitation — file/track a change to the fixed precision constant"],"exampleFix":"// before\nbuilder.set_adjustment(adjustment_price); // panics if scale > FIXED_PRECISION\n// after\nlet adj = Price::new(\n    adjustment_price.as_f64(),\n    FIXED_PRECISION as u8,\n); // quantize to fixed precision first\nbuilder.set_adjustment(adj);","handlingStrategy":"validation","validationCode":"// Rust: quantize the adjustment to the builder's fixed precision first\nlet adj = Price::new(adjustment_f64, FIXED_PRECISION as u8);\nassert!(adjustment_f64.is_finite(), \"adjustment must be finite\");","typeGuard":null,"tryCatchPattern":"let result = std::panic::catch_unwind(|| builder.set_adjustment(adj));","preventionTips":["Always construct adjustment Prices at FIXED_PRECISION","Reject provider data with more decimals than the platform precision","Check mantissa scaling when converting floats to Price"],"tags":["rust","panic","precision","fixed-point","overflow"],"backgroundTag":"value-out-of-range","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}