{"record":{"id":"369c891ede16e025","repo":"nautechsystems/nautilus_trader","slug":"generic-spread-contract-count-overflowed-for-symb","errorCode":null,"errorMessage":"Generic spread contract count overflowed for {symbol}","messagePattern":"Generic spread contract count overflowed for (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/execution/src/models/fee.rs","lineNumber":357,"sourceCode":"            .and_then(|v| mul_checked(v, contracts))?;\n        Money::from_decimal(total, self.commission.currency).map_err(Into::into)\n    }\n}\n\nfn spread_contract_count(instrument: &InstrumentAny) -> anyhow::Result<Decimal> {\n    let instrument_id = instrument.id();\n    let symbol = instrument_id.symbol.as_str();\n    if !instrument.is_spread() || !symbol.contains(GENERIC_SPREAD_ID_SEPARATOR) {\n        return Ok(Decimal::ONE);\n    }\n\n    let mut total = 0_i64;\n\n    for component in symbol.split(GENERIC_SPREAD_ID_SEPARATOR) {\n        let ratio = spread_leg_ratio(component)\n            .ok_or_else(|| anyhow::anyhow!(\"Invalid generic spread leg component: {component}\"))?;\n        total = total.checked_add(ratio).ok_or_else(|| {\n            anyhow::anyhow!(\"Generic spread contract count overflowed for {symbol}\")\n        })?;\n    }\n\n    Ok(total.into())\n}\n\nfn spread_leg_ratio(component: &str) -> Option<i64> {\n    if let Some(rest) = component.strip_prefix(\"((\") {\n        let (ratio, symbol) = rest.split_once(\"))\")?;\n        return spread_leg_ratio_parts(ratio, symbol);\n    }\n\n    let rest = component.strip_prefix('(')?;\n    let (ratio, symbol) = rest.split_once(')')?;\n    spread_leg_ratio_parts(ratio, symbol)\n}\n\nfn spread_leg_ratio_parts(ratio: &str, symbol: &str) -> Option<i64> {","sourceCodeStart":339,"sourceCodeEnd":375,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/execution/src/models/fee.rs#L339-L375","documentation":"While summing generic spread leg ratios into an i64 contract count, `spread_contract_count` uses `checked_add` and raises this error if the running total overflows. It protects against absurdly large or corrupt spread symbols producing an invalid commission.","triggerScenarios":"Calling `get_commission` on a generic spread symbol whose leg ratios sum beyond i64::MAX — practically only possible with pathological/corrupt symbol components carrying huge ratios.","commonSituations":"Corrupted or adversarially crafted instrument IDs; parsing symbols with extremely large numeric leg components.","solutions":["Validate the instrument symbol and its leg ratios come from a trusted source before fee computation.","Cap or sanity-check leg ratios when constructing generic spread instruments.","Investigate the symbol string reported in the message for corruption."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"ratios = [spread_leg_ratio(c) for c in symbol.split(SEP)]\nassert all(r is not None and 0 < r < 10**6 for r in ratios), \"implausible leg ratios\"","typeGuard":null,"tryCatchPattern":"let count = spread_contract_count(symbol).unwrap_or_else(|e| {\n    log::error!(\"overflow for {symbol}: {e}\"); Decimal::ONE\n});","preventionTips":["Bound leg ratio magnitudes when building generic spread instruments.","Treat huge ratio sums as corrupt data and reject the instrument early."],"tags":["overflow","spread","fee","i64","rust"],"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"}