{"record":{"id":"5c7f7cc14326593d","repo":"nautechsystems/nautilus_trader","slug":"invalid-negative-multiplier-v","errorCode":null,"errorMessage":"Invalid negative multiplier: {v}","messagePattern":"Invalid negative multiplier: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/databento/src/decode/primitives.rs","lineNumber":372,"sourceCode":"    if value == dbn::UNDEF_TIMESTAMP {\n        None\n    } else {\n        Some(UnixNanos::from(value))\n    }\n}\n\n/// Decodes a multiplier from the given value, expressed in units of 1e-9.\n/// Uses exact integer arithmetic to avoid precision loss in financial calculations.\n///\n/// # Errors\n///\n/// Returns an error if value is negative (invalid multiplier).\npub fn decode_multiplier(value: i64) -> anyhow::Result<Quantity> {\n    const SCALE: u64 = 1_000_000_000;\n\n    match value {\n        0 | i64::MAX => Ok(quantity_from_whole(1)),\n        v if v < 0 => anyhow::bail!(\"Invalid negative multiplier: {v}\"),\n        v => {\n            let mantissa = v as u64;\n            let mut frac_part = mantissa % SCALE;\n            let mut precision = 9u8;\n            while precision > 0 && frac_part.is_multiple_of(10) {\n                frac_part /= 10;\n                precision -= 1;\n            }\n\n            Ok(Quantity::from_mantissa_exponent_checked(\n                mantissa, -9, precision,\n            )?)\n        }\n    }\n}\n\n/// Decodes a lot size from the given value, expressed in standard whole-number units.\n///","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/databento/src/decode/primitives.rs#L354-L390","documentation":"`decode_multiplier` converts an i64 multiplier (scaled by 1e9) into a `Quantity`, mapping 0 and `i64::MAX` to a default quantity of 1. Negative values are invalid for a contract multiplier and cause this error. It guards instrument definition decoding against nonsensical negative multiplier data.","triggerScenarios":"`decode_multiplier(v)` called with `v < 0`, via `decode_currency_pair`, `decode_futures_contract`, `decode_futures_spread`, `decode_option_multiplier`, or `decode_option_spread` when a definition record's multiplier field is negative.","commonSituations":"Corrupt or unusual Databento definition records (negative multiplier), double-sign encoding mistakes in upstream data, or wrong schema/asset class being fed to the decoder.","solutions":["Inspect the raw definition record's multiplier field and confirm whether the negative value is a data error on the vendor side.","Exclude instruments with negative multipliers before decoding (pre-filter the definitions response).","If 0/i64::MAX-style defaults are what you expect for this asset class, normalize the value before calling (clamp to 0/UNDEF).","Catch the anyhow error at the instrument-decoding site and skip the instrument with a log."],"exampleFix":"// before\nlet mult = decode_multiplier(def.multiplier as i64)?;\n// after\nlet raw = def.multiplier as i64;\nlet mult = if raw < 0 { quantity_from_whole(1) } else { decode_multiplier(raw)? };","handlingStrategy":"validation","validationCode":"fn multiplier_valid(raw: i64) -> bool { raw >= 0 } // 0 and i64::MAX default to 1","typeGuard":"fn is_negative_multiplier(v: i64) -> bool { v < 0 }","tryCatchPattern":"match decode_multiplier(raw) {\n    Ok(q) => q,\n    Err(e) => { log::warn!(\"bad multiplier: {e}\"); quantity_from_whole(1) }\n}","preventionTips":["Pre-filter definition records with negative multiplier fields.","Note that 0 and i64::MAX are already normalized to 1 inside the decoder.","Verify the record comes from the expected schema/asset class."],"tags":["databento","decode","multiplier","validation"],"backgroundTag":"invalid-argument-value","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"}