nautechsystems/nautilus_trader · error · anyhow::Error
invalid negative kline trade count {}
Error message
invalid negative kline trade count {} What it means
A kline message's `num_trades` field was negative, so the `i64` from the SBE/JSON payload could not be converted to `u64`. `parse_kline` maps any `try_from` failure to this error. A trade count can never be negative, so this indicates a corrupt or malformed kline payload.
Source
Thrown at crates/adapters/binance/src/spot/websocket/public_json/parse.rs:385
let volume = parse_non_negative_quantity(&msg.kline.volume, size_precision, "volume")?;
let quote_volume = Decimal::from_str(&msg.kline.quote_volume)
.with_context(|| format!("invalid quote volume `{}`", msg.kline.quote_volume))?;
let taker_buy_base_volume =
Decimal::from_str(&msg.kline.taker_buy_base_volume).with_context(|| {
format!(
"invalid taker buy base volume `{}`",
msg.kline.taker_buy_base_volume
)
})?;
let taker_buy_quote_volume = Decimal::from_str(&msg.kline.taker_buy_quote_volume)
.with_context(|| {
format!(
"invalid taker buy quote volume `{}`",
msg.kline.taker_buy_quote_volume
)
})?;
let count = u64::try_from(msg.kline.num_trades).map_err(|_| {
anyhow::anyhow!(
"invalid negative kline trade count {}",
msg.kline.num_trades
)
})?;
let ts_event =
parse_millis_or_init(msg.kline.close_time, "Spot JSON kline close time", ts_init);
Ok(Some(BinanceBar::new(
bar_type,
open,
high,
low,
close,
volume,
quote_volume,
count,
taker_buy_base_volume,View on GitHub (pinned to 18893faf8b)
Solutions
- Log the full kline payload and report the negative `num_trades` to Binance support as an upstream data issue.
- Verify the SBE schema/decoder version matches the current Binance SBE market-data spec and update the adapter.
- If connecting to a Binance clone/proxy, check its kline serialization for the `num_trades` field.
- Skip the offending kline and resubscribe to the kline stream to resync.
Defensive patterns
Strategy: try-catch
Validate before calling
if msg.kline.num_trades < 0 { // skip or resync kline stream
return Ok(None);
} Try / catch
match parse_kline(&msg) {
Ok(kline) => publish(kline),
Err(e) if e.to_string().contains("trade count") => {
log::warn!("skipping malformed kline: {e}");
}
Err(e) => return Err(e),
} Prevention
- Keep the Binance SBE schema and adapter up to date.
- Log full payloads of anomalous upstream data and report to the exchange.
- Treat u64 conversions of signed exchange fields as fallible and guard them.
When it happens
Trigger: Binance sends a kline whose `num_trades` is a negative integer; `u64::try_from(msg.kline.num_trades)` fails inside `parse_kline` and the error is raised.
Common situations: Protocol/SBE decode bugs or upstream anomalies producing a negative count; running against a non-standard Binance-compatible exchange; corrupted frames from a proxy.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Binance {field} timestamp is outside the UnixNanos range: {v
- invalid {field}='{raw}': {e}
- invalid cumulative_quote_qty='{}' for cumulative_filled_qty=
- Quantity overflow for ticks={ticks}, decimals={decimals}: {e
- invalid price `{value}` at precision {precision}: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/f2ee7181a0ef09e4.
Report an issue: GitHub.