{"record":{"id":"ed32d5f666c7c908","repo":"nautechsystems/nautilus_trader","slug":"invalid-negative-contract-multiplier-value","errorCode":null,"errorMessage":"Invalid negative `contract_multiplier`: {value}","messagePattern":"Invalid negative `contract_multiplier`: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/databento/src/decode/instruments.rs","lineNumber":342,"sourceCode":"        .expiration_ns(expiration)\n        .price_precision(price_increment.precision)\n        .price_increment(price_increment)\n        .multiplier(multiplier)\n        .lot_size(lot_size)\n        .ts_event(ts_event)\n        .ts_init(ts_init)\n        .build()?)\n}\n\nfn decode_option_multiplier(\n    dataset: Option<dbn::Dataset>,\n    contract_multiplier: i32,\n    unit_of_measure_qty: i64,\n) -> anyhow::Result<Quantity> {\n    match (dataset, contract_multiplier) {\n        (Some(dbn::Dataset::OpraPillar), 0 | i32::MAX) => decode_multiplier(unit_of_measure_qty),\n        (Some(dbn::Dataset::OpraPillar), value) if value < 0 => {\n            anyhow::bail!(\"Invalid negative `contract_multiplier`: {value}\")\n        }\n        (Some(dbn::Dataset::OpraPillar), value) => {\n            Ok(Quantity::from_mantissa_exponent(value as u64, 0, 0))\n        }\n        _ => decode_multiplier(unit_of_measure_qty),\n    }\n}\n\n/// Decodes a Databento instrument definition message into an `OptionSpread` instrument.\n///\n/// # Errors\n///\n/// Returns an error if parsing or constructing `OptionSpread` fails.\npub fn decode_option_spread(\n    msg: &dbn::InstrumentDefMsg,\n    instrument_id: InstrumentId,\n    ts_init: Option<UnixNanos>,\n    decode_config: Option<&DatabentoDecodeConfig>,","sourceCodeStart":324,"sourceCodeEnd":360,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/databento/src/decode/instruments.rs#L324-L360","documentation":"`decode_option_multiplier` rejects a negative `contract_multiplier` for OPRA Pillar options. The multiplier must be a positive i32 or a sentinel (0 or i32::MAX meaning derive from `unit_of_measure_qty`); any other negative value indicates corrupt or semantically invalid instrument definition data.","triggerScenarios":"Decoding a Databento option instrument definition (via `decode_option_contract`) where the OPRA dataset record carries `contract_multiplier < 0` and it is not the 0 or i32::MAX sentinel.","commonSituations":"Corrupted or anomalous Databento instrument definition records; upstream schema changes introducing negative multipliers; feeding synthetic/test data with negative values.","solutions":["Inspect the instrument definition record and fix the source data multiplier","Use 0 or i32::MAX to trigger derivation from `unit_of_measure_qty` instead of a negative value","Add pre-validation of multiplier values before decoding","Report the record to Databento support if it appears to be bad upstream data"],"exampleFix":"// before\ncontract_multiplier: -100\n// after\ncontract_multiplier: 100 // or 0 / i32::MAX to derive from unit_of_measure_qty","handlingStrategy":"validation","validationCode":"fn validate_multiplier(m: i32) -> Result<(), String> {\n    if m < 0 && m != i32::MAX { Err(format!(\"contract_multiplier must be >=0 or i32::MAX, got {m}\")) } else { Ok(()) }\n}","typeGuard":null,"tryCatchPattern":"match decode_option_contract(def) {\n    Ok(inst) => inst,\n    Err(e) if e.to_string().contains(\"Invalid negative `contract_multiplier`\") => { /* skip or correct the record */ }\n    Err(e) => return Err(e),\n}","preventionTips":["Validate instrument definition fields before decoding","Treat negative multipliers (other than i32::MAX) as corrupt data at ingest","Prefer the 0/i32::MAX sentinel to derive from unit_of_measure_qty","Pin and test against known-good Databento definition data"],"tags":["rust","databento","instruments","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"}