{"record":{"id":"e4b028427b54e8eb","repo":"nautechsystems/nautilus_trader","slug":"effective-raw-scale-should-fit-in-moneyraw-e4b028","errorCode":null,"errorMessage":"effective raw scale should fit in MoneyRaw","messagePattern":"effective raw scale should fit in MoneyRaw","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/types/money.rs","lineNumber":690,"sourceCode":"        self.as_f64() * rhs\n    }\n}\n\nimpl Div<f64> for Money {\n    type Output = f64;\n    fn div(self, rhs: f64) -> Self::Output {\n        self.as_f64() / rhs\n    }\n}\n\nimpl Debug for Money {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        if self.currency.precision > crate::types::fixed::MAX_FLOAT_PRECISION {\n            write!(f, \"{}({}, {})\", stringify!(Money), self.raw, self.currency)\n        } else {\n            let precision = self.currency.precision;\n            let scale = MoneyRaw::try_from(raw_scale(precision))\n                .expect(\"effective raw scale should fit in MoneyRaw\");\n            let currency_scale = MoneyRaw::pow(10, u32::from(precision));\n            let amount = self.raw / (scale / currency_scale);\n\n            if precision == 0 {\n                write!(f, \"{}({}, {})\", stringify!(Money), amount, self.currency)\n            } else {\n                let sign = if amount < 0 { \"-\" } else { \"\" };\n                let amount_abs = amount.unsigned_abs();\n                let currency_scale = currency_scale.unsigned_abs();\n                let whole = amount_abs / currency_scale;\n                let fraction = amount_abs % currency_scale;\n                write!(\n                    f,\n                    \"{}({sign}{whole}.{fraction:0>width$}, {})\",\n                    stringify!(Money),\n                    self.currency,\n                    width = usize::from(precision),\n                )","sourceCodeStart":672,"sourceCodeEnd":708,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/types/money.rs#L672-L708","documentation":"Money's Display impl (fmt) divides the raw value by the effective raw scale to render the amount. The scale 10^precision is converted into MoneyRaw via try_from, and if the currency precision implies a scale not representable in MoneyRaw the conversion expect panics with this message. Displaying can therefore panic on pathological precision values.","triggerScenarios":"Formatting (println!, format!, to_string, logging) any Money whose currency precision exceeds what MoneyRaw can represent as 10^precision (roughly precision > 38 for i128 raw, lower in non-high-precision builds).","commonSituations":"A Currency configured with an invalid/extreme precision (bad asset definition from a config or exchange adapter); debugging output of a mis-constructed Money. Note the code prints raw fallback only when precision > MAX_FLOAT_PRECISION, so extreme-but-below-that precisions still hit the scale conversion.","solutions":["Correct the Currency's precision to a realistic value (typically 0-9 decimal places).","Validate currency precision when constructing/registering the currency.","Avoid formatting until the currency definition is fixed; inspect the raw value instead."],"exampleFix":"// before\nlet cur = Currency::from(\"XYZ\").with_precision(45);\nprintln!(\"{}\", Money::new(dec, cur)); // panics in fmt\n// after\nlet cur = Currency::from(\"XYZ\").with_precision(8); // sane precision\nprintln!(\"{}\", Money::new(dec, cur));","handlingStrategy":"validation","validationCode":"if currency.precision > 38 { // 10^38 overflows i128 MoneyRaw\n    panic!(\"currency precision {} too large for display\", currency.precision);\n}\nformat!(\"{}\", money)","typeGuard":"fn printable(currency: &Currency) -> bool {\n    u32::from(currency.precision) <= 38 && u64::from(currency.precision) <= u32::MAX.into()\n}","tryCatchPattern":null,"preventionTips":["Validate currency precision (realistic 0-9 decimals) at currency registration time.","Audit exchange adapters that synthesize Currency definitions from venue metadata.","Test that Display formatting works for every currency your system registers at startup."],"tags":["rust","overflow","money","display","precision"],"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"}