{"record":{"id":"b315389ede9ed9c0","repo":"nautechsystems/nautilus_trader","slug":"price-decimals-decimals-exceeds-maximum-max-dec","errorCode":null,"errorMessage":"price decimals {decimals} exceeds maximum {MAX_DECIMALS}","messagePattern":"price decimals (.+?) exceeds maximum (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/lighter/src/common/parse.rs","lineNumber":46,"sourceCode":"    datetime::{NANOSECONDS_IN_MILLISECOND, NANOSECONDS_IN_SECOND},\n};\nuse nautilus_model::types::{Price, Quantity, fixed::FIXED_PRECISION};\nuse rust_decimal::Decimal;\n\n/// Maximum decimal places that fit into Nautilus [`Price`] / [`Quantity`].\npub const MAX_DECIMALS: u8 = FIXED_PRECISION;\n\n/// Converts a Lighter price tick count into a Nautilus [`Price`].\n///\n/// Lighter encodes limit and trigger prices as `u32` multiples of `10^-decimals`\n/// quote-asset units. The conversion uses pure integer arithmetic via\n/// [`Price::from_mantissa_exponent`].\n///\n/// # Errors\n///\n/// Returns an error if `decimals` exceeds [`MAX_DECIMALS`].\npub fn parse_price_from_ticks(ticks: u32, decimals: u8) -> anyhow::Result<Price> {\n    anyhow::ensure!(\n        decimals <= MAX_DECIMALS,\n        \"price decimals {decimals} exceeds maximum {MAX_DECIMALS}\",\n    );\n    let exponent = -(decimals as i8);\n    Ok(Price::from_mantissa_exponent(\n        i64::from(ticks),\n        exponent,\n        decimals,\n    ))\n}\n\n/// Converts a Lighter base-amount tick count into a Nautilus [`Quantity`].\n///\n/// Order sizes on the wire are signed `i64` multiples of `10^-decimals`\n/// base-asset units. Nautilus [`Quantity`] is non-negative, so a negative\n/// `ticks` value is rejected: callers (e.g. position parsers) extract the\n/// sign separately before invoking this parser.\n///","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/lighter/src/common/parse.rs#L28-L64","documentation":"`parse_price_from_ticks` converts an integer tick value and a decimal count into a Nautilus `Price`. It rejects any `decimals` value above `MAX_DECIMALS` (the precision limit `Price::from_mantissa_exponent` supports), because the resulting price precision would be unrepresentable.","triggerScenarios":"Calling `parse_price_from_ticks(ticks, decimals)` with `decimals > MAX_DECIMALS`, e.g. when parsing an instrument definition whose price precision exceeds the adapter's maximum.","commonSituations":"Loading a Lighter instrument with unusually high price precision; misreading a market's quoted decimals field; hardcoding decimals from a different market.","solutions":["Check the market's price precision and ensure it is <= MAX_DECIMALS before parsing.","Round or scale the tick value to a supported precision if the source data has excess decimals.","Inspect `MAX_DECIMALS` in crates/adapters/lighter/src/common/parse.rs to know the allowed limit."],"exampleFix":"// before\nlet price = parse_price_from_ticks(ticks, 20)?;\n// after\nlet decimals = decimals.min(MAX_DECIMALS);\nlet price = parse_price_from_ticks(ticks, decimals)?;","handlingStrategy":"validation","validationCode":"if decimals > lighter::parse::MAX_DECIMALS {\n    decimals = lighter::parse::MAX_DECIMALS; // or reject the instrument\n}","typeGuard":"fn price_precision_supported(d: u8) -> bool { d <= lighter::parse::MAX_DECIMALS }","tryCatchPattern":"let price = parse_price_from_ticks(ticks, decimals)\n    .map_err(|e| { eprintln!(\"price parse failed: {e}\"); e })?;","preventionTips":["Check instrument price precision against MAX_DECIMALS when loading definitions.","Reject or round instruments exceeding the precision limit at load time.","Avoid hardcoding decimals copied from other venues."],"tags":["price","precision","validation","lighter"],"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"}