{"record":{"id":"2b67b5dd96827150","repo":"nautechsystems/nautilus_trader","slug":"invalid-stepsize-of-0","errorCode":null,"errorMessage":"Invalid stepSize of 0","messagePattern":"Invalid stepSize of 0","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/binance/src/common/parse.rs","lineNumber":807,"sourceCode":"        .filters\n        .iter()\n        .find(|filter| filter.filter_type == \"LOT_SIZE\")\n        .context(\"Missing LOT_SIZE in symbol filters\")?;\n\n    let tick_size = decimal_price(\n        price_filter\n            .tick_size\n            .as_deref()\n            .context(\"Missing PRICE_FILTER tickSize\")?,\n    )?;\n    anyhow::ensure!(!tick_size.is_zero(), \"Invalid tickSize of 0\");\n    let step_size = decimal_quantity(\n        lot_filter\n            .step_size\n            .as_deref()\n            .context(\"Missing LOT_SIZE stepSize\")?,\n    )?;\n    anyhow::ensure!(!step_size.is_zero(), \"Invalid stepSize of 0\");\n\n    let instrument = CurrencyPair::new(\n        InstrumentId::new(\n            Symbol::from_str_unchecked(&symbol.symbol),\n            Venue::new(BINANCE),\n        ),\n        Symbol::new(&symbol.symbol),\n        get_currency(&symbol.base_asset),\n        get_currency(&symbol.quote_asset),\n        tick_size.precision,\n        step_size.precision,\n        tick_size,\n        step_size,\n        None,\n        Some(step_size),\n        optional_decimal_quantity(lot_filter.max_qty.as_deref(), step_size.precision)?,\n        optional_decimal_quantity(lot_filter.min_qty.as_deref(), step_size.precision)?,\n        None,","sourceCodeStart":789,"sourceCodeEnd":825,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/a4b06ed870971b5671d12754ea138a3ab99b1dec/crates/adapters/binance/src/common/parse.rs#L789-L825","documentation":"Companion to the Spot tickSize check: decimal_quantity parses LOT_SIZE.stepSize and the code enforces it is non-zero. A zero step size cannot define quantity precision or valid order increments, so the parse aborts.","triggerScenarios":"Spot exchangeInfo LOT_SIZE with \"stepSize\": \"0\" for the symbol being parsed — placeholder filters or corrupted payloads.","commonSituations":"Pre-listing symbols; stale caches or fixtures with zeroed filters; venue-side data issues.","solutions":["Check the live Spot exchangeInfo stepSize for the symbol.","Skip symbols with a zero stepSize during loading.","Refresh cached exchangeInfo data.","Report persistent zero stepSize on an actively trading pair."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"fn spot_step_size_is_valid(symbol: &BinanceSymbolJson) -> bool {\n    symbol\n        .filters\n        .iter()\n        .find(|f| f.filter_type == \"LOT_SIZE\")\n        .and_then(|f| f.step_size.as_deref())\n        .map(|t| {\n            rust_decimal::Decimal::from_str(t)\n                .map(|d| !d.is_zero())\n                .unwrap_or(false)\n        })\n        .unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":"match parse_spot_instrument_json_with_fees(&symbol, None, None, ts_event, ts_init) {\n    Ok(inst) => instruments.push(inst),\n    Err(e) if e.to_string().contains(\"Invalid stepSize of 0\") => {\n        tracing::warn!(symbol = %symbol.symbol, \"zero stepSize, skipping\")\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Pre-check LOT_SIZE stepSize is non-zero when filtering symbols.","Refresh cached spot exchangeInfo snapshots.","Report pairs that stay at stepSize 0 while in TRADING status."],"tags":["binance","spot","step-size","lot-size","rust"],"backgroundTag":"invalid-step-size","analyzedSha":"a4b06ed870971b5671d12754ea138a3ab99b1dec","analyzedAt":"2026-08-16T22:54:50.089Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}