nautechsystems/nautilus_trader · error
negative candle volume `{}`
Error message
negative candle volume `{}` What it means
parse_candle_bar checks candle.volume_base with is_sign_positive and rejects negative (or NaN) base volume, since Bar volume is a non-negative Quantity. Negative volume indicates corrupt or mis-scaled upstream candle data. The offending value is embedded in the message.
Source
Thrown at crates/adapters/lighter/src/http/parse.rs:222
"non-positive candle close `{}`",
candle.close
);
let timestamp_ms =
u64::try_from(candle.timestamp).context("negative Lighter candle timestamp")?;
let ts_event = parse_millis_to_nanos(timestamp_ms)?;
let price_precision = instrument.price_precision();
let size_precision = instrument.size_precision();
let open = Price::from_decimal_dp(candle.open, price_precision)
.map_err(|e| anyhow::anyhow!("invalid candle open: {e}"))?;
let high = Price::from_decimal_dp(candle.high, price_precision)
.map_err(|e| anyhow::anyhow!("invalid candle high: {e}"))?;
let low = Price::from_decimal_dp(candle.low, price_precision)
.map_err(|e| anyhow::anyhow!("invalid candle low: {e}"))?;
let close = Price::from_decimal_dp(candle.close, price_precision)
.map_err(|e| anyhow::anyhow!("invalid candle close: {e}"))?;
anyhow::ensure!(
candle.volume_base.is_sign_positive(),
"negative candle volume `{}`",
candle.volume_base,
);
let volume = Quantity::from_decimal_dp(candle.volume_base, size_precision)
.map_err(|e| anyhow::anyhow!("invalid candle volume: {e}"))?;
Bar::new_checked(bar_type, open, high, low, close, volume, ts_event, ts_init)
.context("failed to construct Bar from Lighter candle")
}
/// Parses a Lighter historical funding row into a Nautilus [`FundingRateUpdate`].
///
/// Lighter returns `rate` as a magnitude and `direction` as the side paying
/// the funding. Nautilus uses the conventional signed rate: positive when
/// longs pay shorts and negative when shorts pay longs.
///
/// # ErrorsView on GitHub (pinned to 18893faf8b)
Solutions
- Filter candles with negative volume_base before parsing
- Inspect the raw API response for negative or NaN volume values
- Verify the adapter's volume field mapping matches the current Lighter API schema
- Correct test fixtures to use non-negative volumes
Example fix
// before let bars = candles.iter().map(|c| parse_candle_bar(c, ...)).collect::<Result<Vec<_>>>()?; // after let bars = candles.iter().filter(|c| c.volume_base.is_sign_positive()).map(|c| parse_candle_bar(c, ...)).collect::<Result<Vec<_>>>()?;
Defensive patterns
Strategy: validation
Validate before calling
if !candle.volume_base.is_sign_positive() {
return Err(anyhow::anyhow!("skip candle: negative volume {}", candle.volume_base));
} Type guard
fn has_valid_volume(c: &LighterCandle) -> bool {
c.volume_base.is_sign_positive() && c.volume_base.is_finite()
} Try / catch
let bar = match parse_candle_bar(&candle, bar_type, instrument, ts_init) {
Ok(b) => b,
Err(e) if e.to_string().contains("negative candle volume") => continue,
Err(e) => return Err(e),
}; Prevention
- Filter candles on volume_base.is_sign_positive() before parsing
- Verify volume field mapping against the current Lighter API schema
- Treat NaN as invalid (it fails is_sign_positive) and filter it too
- Keep fixtures with realistic non-negative volumes
When it happens
Trigger: parse_candle_bar receiving a LighterCandle with volume_base < 0 (or NaN, which fails is_sign_positive) when parsing the candles endpoint via parse_bars.
Common situations: Upstream API glitches or sign/scaling changes in the volume field; fixtures with negative volumes; data feeds during exchange incidents.
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
- non-positive candle open `{}`
- non-positive candle high `{}`
- non-positive candle low `{}`
- non-positive candle close `{}`
- invalid negative order-book update ID
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/c8f02db4c251004a.
Report an issue: GitHub.