nautechsystems/nautilus_trader · error
Invalid negative `contract_multiplier`: {value}
Error message
Invalid negative `contract_multiplier`: {value} What it means
`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.
Source
Thrown at crates/adapters/databento/src/decode/instruments.rs:342
.expiration_ns(expiration)
.price_precision(price_increment.precision)
.price_increment(price_increment)
.multiplier(multiplier)
.lot_size(lot_size)
.ts_event(ts_event)
.ts_init(ts_init)
.build()?)
}
fn decode_option_multiplier(
dataset: Option<dbn::Dataset>,
contract_multiplier: i32,
unit_of_measure_qty: i64,
) -> anyhow::Result<Quantity> {
match (dataset, contract_multiplier) {
(Some(dbn::Dataset::OpraPillar), 0 | i32::MAX) => decode_multiplier(unit_of_measure_qty),
(Some(dbn::Dataset::OpraPillar), value) if value < 0 => {
anyhow::bail!("Invalid negative `contract_multiplier`: {value}")
}
(Some(dbn::Dataset::OpraPillar), value) => {
Ok(Quantity::from_mantissa_exponent(value as u64, 0, 0))
}
_ => decode_multiplier(unit_of_measure_qty),
}
}
/// Decodes a Databento instrument definition message into an `OptionSpread` instrument.
///
/// # Errors
///
/// Returns an error if parsing or constructing `OptionSpread` fails.
pub fn decode_option_spread(
msg: &dbn::InstrumentDefMsg,
instrument_id: InstrumentId,
ts_init: Option<UnixNanos>,
decode_config: Option<&DatabentoDecodeConfig>,View on GitHub (pinned to 18893faf8b)
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
Example fix
// before contract_multiplier: -100 // after contract_multiplier: 100 // or 0 / i32::MAX to derive from unit_of_measure_qty
Defensive patterns
Strategy: validation
Validate before calling
fn validate_multiplier(m: i32) -> Result<(), String> {
if m < 0 && m != i32::MAX { Err(format!("contract_multiplier must be >=0 or i32::MAX, got {m}")) } else { Ok(()) }
} Try / catch
match decode_option_contract(def) {
Ok(inst) => inst,
Err(e) if e.to_string().contains("Invalid negative `contract_multiplier`") => { /* skip or correct the record */ }
Err(e) => return Err(e),
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Corrupted or anomalous Databento instrument definition records; upstream schema changes introducing negative multipliers; feeding synthetic/test data with negative values.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Either instrument_ids or contracts must be provided
- No symbols provided
- instrument update lock poisoned
- {e}
- {FAILED}: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/ed32d5f666c7c908.
Report an issue: GitHub.