{"record":{"id":"b07b5443617b3ded","repo":"nautechsystems/nautilus_trader","slug":"invalid-negative-kline-trade-count","errorCode":null,"errorMessage":"invalid negative kline trade count {}","messagePattern":"invalid negative kline trade count (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/binance/src/common/parse.rs","lineNumber":1381,"sourceCode":"        let volume_mantissa = i128::from_le_bytes(kline.volume);\n        let volume_dec =\n            Decimal::from_i128_with_scale(volume_mantissa, (-klines.qty_exponent as i32) as u32);\n        let volume = Quantity::from_decimal_dp(volume_dec, size_precision)?;\n\n        let quote_volume = Decimal::from_i128_with_scale(\n            i128::from_le_bytes(kline.quote_volume),\n            (-klines.price_exponent as i32) as u32,\n        );\n        let taker_buy_base_volume = Decimal::from_i128_with_scale(\n            i128::from_le_bytes(kline.taker_buy_base_volume),\n            (-klines.qty_exponent as i32) as u32,\n        );\n        let taker_buy_quote_volume = Decimal::from_i128_with_scale(\n            i128::from_le_bytes(kline.taker_buy_quote_volume),\n            (-klines.price_exponent as i32) as u32,\n        );\n        let count = u64::try_from(kline.num_trades).map_err(|_| {\n            anyhow::anyhow!(\"invalid negative kline trade count {}\", kline.num_trades)\n        })?;\n        let ts_event = parse_micros(kline.close_time, \"Spot SBE kline close time\")?;\n\n        let bar = crate::common::bar::BinanceBar::new(\n            bar_type,\n            open,\n            high,\n            low,\n            close,\n            volume,\n            quote_volume,\n            count,\n            taker_buy_base_volume,\n            taker_buy_quote_volume,\n            ts_event,\n            ts_init,\n        );\n        bars.push(bar);","sourceCodeStart":1363,"sourceCodeEnd":1399,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/a4b06ed870971b5671d12754ea138a3ab99b1dec/crates/adapters/binance/src/common/parse.rs#L1363-L1399","documentation":"When decoding Binance Spot klines received over the SBE (binary) market-data channel, the per-kline trade count is carried as a signed i64 and converted to u64 for NautilusTrader's Bar. A negative value cannot occur in a well-formed feed, so this error signals malformed or desynchronized SBE decoding — most often a schema/version mismatch between the adapter's generated codecs and the venue's current SBE templates, or a misaligned buffer.","triggerScenarios":"Subscribing to Spot SBE kline streams (or replaying captured SBE frames) where the decoded numTrades is negative — typically after Binance updates its SBE schema while the adapter build predates it, or when a recorded byte stream is fed at the wrong offset.","commonSituations":"Venue ships an SBE template revision; a cached/recorded binary stream is replayed against a different adapter version; stream resubscription after a mid-session protocol switch desynchronizes the decoder.","solutions":["Update NautilusTrader to the latest release so the bundled SBE codecs match the venue's current schema.","Unsubscribe and resubscribe (or reconnect) the SBE stream to re-sync decoding from a message boundary.","If it persists, capture the raw frame and symbol/interval and report it to the adapter maintainers.","As a workaround, configure the data client to use the JSON market-data channel instead of SBE."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"fn kline_trade_count_is_valid(num_trades: i64) -> bool {\n    num_trades >= 0\n}","typeGuard":"fn has_valid_trade_count(num_trades: i64) -> bool {\n    num_trades >= 0\n}","tryCatchPattern":"// where decoded SBE klines are consumed\nlet count = match u64::try_from(kline.num_trades) {\n    Ok(c) => c,\n    Err(_) => {\n        tracing::error!(num_trades = kline.num_trades, \"malformed SBE kline, resubscribing\");\n        resubscribe_kline_stream();\n        continue;\n    }\n};","preventionTips":["Keep the adapter updated so bundled SBE codecs track the venue's current schema version.","Resubscribe/reconnect the SBE stream on decode anomalies instead of continuing a desynchronized decoder.","Capture raw frames when the error recurs and attach symbol/interval when reporting.","Fall back to the JSON market-data channel for critical pipelines if SBE instability persists."],"tags":["binance","spot","sbe","klines","market-data","rust"],"backgroundTag":"binary-protocol-decode-error","analyzedSha":"a4b06ed870971b5671d12754ea138a3ab99b1dec","analyzedAt":"2026-08-16T22:54:50.089Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}