nautechsystems/nautilus_trader · error
invalid candle close: {e}
Error message
invalid candle close: {e} What it means
This wraps a failure converting the candle's close Decimal to a Price at the instrument's price_precision in parse_candle_bar. Price::from_decimal_dp refused the value, so the Bar cannot be built; the underlying reason is attached as the error cause.
Source
Thrown at crates/adapters/lighter/src/http/parse.rs:221
candle.close > Decimal::ZERO,
"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.
///View on GitHub (pinned to 18893faf8b)
Solutions
- Read the chained cause to identify why from_decimal_dp rejected the close
- Verify the instrument's price_precision matches the market's actual tick size
- Sanitize finite-ness and scale of candle decimals before parsing
- Check the raw Lighter candles payload for bad close values
Example fix
// before let close = Price::from_decimal_dp(candle.close, price_precision)?; // after let close = Price::from_decimal_dp(candle.close.round_dp(price_precision as u32), price_precision)?;
Defensive patterns
Strategy: try-catch
Validate before calling
anyhow::ensure!(candle.close.is_finite(), "non-finite candle close: {}", candle.close); Type guard
fn convertible_close(c: &LighterCandle, precision: u8) -> bool {
c.close.is_finite() && c.close > Decimal::ZERO
} Try / catch
let close = Price::from_decimal_dp(candle.close, price_precision)
.map_err(|e| anyhow::anyhow!("invalid candle close: {e}"))
.with_context(|| format!("candle for {}", instrument.id()))?; Prevention
- Ensure instrument price_precision accommodates the API's decimal scale
- Sanitize closes (finite, positive) before conversion
- Pin adapter expectations to the current Lighter candles schema
- Fail with context including instrument id to speed diagnosis
When it happens
Trigger: LighterCandle.close failing Price::from_decimal_dp(close, price_precision) while parsing candles through parse_bars — non-finite values, or decimals incompatible with the instrument's precision.
Common situations: Malformed upstream closes (NaN/inf); mismatched instrument precision; adapter/version drift where the API returns differently scaled decimals.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- invalid candle open: {e}
- invalid candle high: {e}
- invalid candle low: {e}
- invalid candle volume: {e}
- invalid candle open: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/93d5c62b9c2e9c4b.
Report an issue: GitHub.