{"record":{"id":"6ab70fa10d8b8a06","repo":"nautechsystems/nautilus_trader","slug":"non-positive-candle-high","errorCode":null,"errorMessage":"non-positive candle high `{}`","messagePattern":"non-positive candle high `(.+?)`","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/lighter/src/http/parse.rs","lineNumber":192,"sourceCode":"}\n\n/// Parses a Lighter candle into a Nautilus [`Bar`].\n///\n/// # Errors\n///\n/// Returns an error if any price, volume, or timestamp field cannot be converted.\npub fn parse_candle_bar(\n    candle: &LighterCandle,\n    bar_type: BarType,\n    instrument: &InstrumentAny,\n    ts_init: UnixNanos,\n) -> anyhow::Result<Bar> {\n    anyhow::ensure!(\n        candle.open > Decimal::ZERO,\n        \"non-positive candle open `{}`\",\n        candle.open\n    );\n    anyhow::ensure!(\n        candle.high > Decimal::ZERO,\n        \"non-positive candle high `{}`\",\n        candle.high\n    );\n    anyhow::ensure!(\n        candle.low > Decimal::ZERO,\n        \"non-positive candle low `{}`\",\n        candle.low\n    );\n    anyhow::ensure!(\n        candle.close > Decimal::ZERO,\n        \"non-positive candle close `{}`\",\n        candle.close\n    );\n\n    let timestamp_ms =\n        u64::try_from(candle.timestamp).context(\"negative Lighter candle timestamp\")?;\n    let ts_event = parse_millis_to_nanos(timestamp_ms)?;","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/lighter/src/http/parse.rs#L174-L210","documentation":"parse_candle_bar requires a candle's high price to be strictly positive before constructing a Price. A non-positive high indicates malformed, placeholder, or corrupt data from the Lighter candles endpoint. The error message embeds the offending value.","triggerScenarios":"parse_candle_bar receiving a LighterCandle with high <= 0 while parsing a candles HTTP response via parse_bars.","commonSituations":"Illiquid or empty markets returning zeroed candles; mock/fixture data with zeros; upstream API data corruption during incidents.","solutions":["Filter out candles with high <= 0 before parsing","Inspect the raw Lighter API response for the offending candle","Verify the market is active/trading and the requested time range contains real trades","Correct fixture data used in tests to hold positive OHLC"],"exampleFix":"// before\nfor candle in candles { bars.push(parse_candle_bar(candle, ...)?); }\n// after\nfor candle in candles.into_iter().filter(|c| c.high > Decimal::ZERO) { bars.push(parse_candle_bar(candle, ...)?); }","handlingStrategy":"validation","validationCode":"if candle.high <= Decimal::ZERO {\n    return Err(anyhow::anyhow!(\"skip candle: non-positive high {}\", candle.high));\n}","typeGuard":"fn has_positive_ohlc(c: &LighterCandle) -> bool {\n    c.open > Decimal::ZERO && c.high > Decimal::ZERO && c.low > Decimal::ZERO && c.close > Decimal::ZERO\n}","tryCatchPattern":"let bar = match parse_candle_bar(&candle, bar_type, instrument, ts_init) {\n    Ok(b) => b,\n    Err(e) if e.to_string().contains(\"non-positive candle high\") => continue,\n    Err(e) => return Err(e),\n};","preventionTips":["Check high > 0 alongside the other OHLC fields before parsing","Verify upstream data quality for illiquid markets","Avoid zero-filled mock data in tests","Skip-and-log invalid candles in batch ingestion"],"tags":["rust","data-validation","candles","adapter"],"backgroundTag":"invalid-argument-value","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}