nautechsystems/nautilus_trader · error
non-positive candle open `{}`
Error message
non-positive candle open `{}` What it means
parse_candle_bar validates that a Lighter candle's open price is strictly positive before building a Bar. Lighter data must have OHLC values > 0 (Price cannot be zero or negative); a non-positive open means corrupt, placeholder, or malformed API data. The error includes the offending value.
Source
Thrown at crates/adapters/lighter/src/http/parse.rs:187
trade_id,
ts_event,
ts_init,
)
.context("failed to construct TradeTick from Lighter trade")
}
/// Parses a Lighter candle into a Nautilus [`Bar`].
///
/// # Errors
///
/// Returns an error if any price, volume, or timestamp field cannot be converted.
pub fn parse_candle_bar(
candle: &LighterCandle,
bar_type: BarType,
instrument: &InstrumentAny,
ts_init: UnixNanos,
) -> anyhow::Result<Bar> {
anyhow::ensure!(
candle.open > Decimal::ZERO,
"non-positive candle open `{}`",
candle.open
);
anyhow::ensure!(
candle.high > Decimal::ZERO,
"non-positive candle high `{}`",
candle.high
);
anyhow::ensure!(
candle.low > Decimal::ZERO,
"non-positive candle low `{}`",
candle.low
);
anyhow::ensure!(
candle.close > Decimal::ZERO,
"non-positive candle close `{}`",
candle.closeView on GitHub (pinned to 18893faf8b)
Solutions
- Skip or filter candles with open <= 0 before calling parse_candle_bar/parse_bars
- Check the upstream Lighter API response for corrupt or placeholder candle records
- Confirm the instrument/market is active and has traded (delisted or never-traded markets may yield zeros)
- Validate fixture/test data contains positive OHLC values
Example fix
// before let bars: Vec<Bar> = candles.iter().map(|c| parse_candle_bar(c, bar_type, &inst, ts_init)).collect::<Result<_>>()?; // after let bars: Vec<Bar> = candles.iter().filter(|c| c.open > Decimal::ZERO).map(|c| parse_candle_bar(c, bar_type, &inst, ts_init)).collect::<Result<_>>()?;
Defensive patterns
Strategy: validation
Validate before calling
if candle.open <= Decimal::ZERO {
return Err(anyhow::anyhow!("skip candle: non-positive open {}", candle.open));
} Type guard
fn has_positive_ohlc(c: &LighterCandle) -> bool {
c.open > Decimal::ZERO && c.high > Decimal::ZERO && c.low > Decimal::ZERO && c.close > Decimal::ZERO
} Try / catch
let bar = match parse_candle_bar(&candle, bar_type, instrument, ts_init) {
Ok(b) => b,
Err(e) if e.to_string().contains("non-positive candle open") => continue,
Err(e) => return Err(e),
}; Prevention
- Pre-filter candles for positive OHLC before parsing
- Validate market activity for the requested interval (empty markets yield zeros)
- Keep fixtures free of placeholder zero values
- Log and skip invalid candles instead of failing whole batch parses where acceptable
When it happens
Trigger: parse_candle_bar receiving a LighterCandle whose open field is <= 0 (zero or negative Decimal), typically via parse_bars processing a /candles HTTP response.
Common situations: Exchange API returning zeroed-out candles for illiquid/new markets or delisted pairs; fixtures or mocks with placeholder zeros; upstream data glitches during outages.
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 high `{}`
- non-positive candle low `{}`
- non-positive candle close `{}`
- negative candle volume `{}`
- Unsupported bar specification for AX: {step}-{:?}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/b6f09bfff1d8b986.
Report an issue: GitHub.