nautechsystems/nautilus_trader · error · anyhow::Error
invalid volume: {e}
Error message
invalid volume: {e} What it means
The candle volume fails `Quantity::from_decimal_dp(candle.volume, size_precision)` during Bar conversion, wrapped as "invalid volume". The volume value from the Hyperliquid candle cannot be parsed or does not fit the instrument's size precision.
Source
Thrown at crates/adapters/hyperliquid/src/data.rs:2082
size_precision: u8,
) -> anyhow::Result<Bar> {
let ts_event = millis_to_nanos(candle.timestamp)?;
let close_boundary = candle
.end_timestamp
.checked_add(1)
.context("candle close boundary overflow")?;
let ts_init = millis_to_nanos(close_boundary)?;
let open = Price::from_decimal_dp(candle.open, price_precision)
.map_err(|e| anyhow::anyhow!("invalid open price: {e}"))?;
let high = Price::from_decimal_dp(candle.high, price_precision)
.map_err(|e| anyhow::anyhow!("invalid high price: {e}"))?;
let low = Price::from_decimal_dp(candle.low, price_precision)
.map_err(|e| anyhow::anyhow!("invalid low price: {e}"))?;
let close = Price::from_decimal_dp(candle.close, price_precision)
.map_err(|e| anyhow::anyhow!("invalid close price: {e}"))?;
let volume = Quantity::from_decimal_dp(candle.volume, size_precision)
.map_err(|e| anyhow::anyhow!("invalid volume: {e}"))?;
Ok(Bar::new(
bar_type, open, high, low, close, volume, ts_event, ts_init,
))
}
/// Request bars from HTTP API.
async fn request_bars_from_http(
http_client: HyperliquidHttpClient,
bar_type: BarType,
start: Option<Timestamp>,
end: Option<Timestamp>,
limit: Option<u32>,
instruments: Arc<AtomicMap<InstrumentId, InstrumentAny>>,
) -> anyhow::Result<Vec<Bar>> {
// Get instrument details for precision
let instrument_id = bar_type.instrument_id();
let instrument = instrumentsView on GitHub (pinned to 18893faf8b)
Solutions
- Verify the instrument's size_precision matches the Hyperliquid market.
- Inspect the raw candle `volume` value and correct the source data.
- Re-request the candles; retry in case of a transient bad payload.
- Normalize custom volume values to plain decimals within size_precision.
Example fix
// before
Candle { volume: "1e-9".to_string(), .. } // size_precision = 4
// after
Candle { volume: "0.0000".to_string(), .. } // or drop the candle as dust Defensive patterns
Strategy: validation
Validate before calling
fn volume_fits_precision(volume: &str, size_precision: u8) -> bool {
rust_decimal::Decimal::from_str(volume)
.map(|d| d.scale() <= size_precision as u32 && d >= rust_decimal::Decimal::ZERO)
.unwrap_or(false)
} Try / catch
match result {
Err(e) if e.to_string().contains("invalid volume") => {
tracing::warn!("dropping candle with bad volume: {e:#}");
}
r => r?,
} Prevention
- Verify size_precision matches the market before requesting bars.
- Treat zero/near-zero volumes explicitly instead of relying on parsing.
- Pre-normalize custom volume strings to plain decimals within size_precision.
When it happens
Trigger: Candle payload whose `volume` is malformed (empty, non-decimal) or has more decimals than the instrument's configured size_precision while constructing a Bar.
Common situations: Size precision misconfigured for the market; bad or aggregated candle data; custom fixtures with unrealistic volume strings (e.g. negative or over-precise).
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 open price: {e}
- invalid high price: {e}
- invalid low price: {e}
- invalid close price: {e}
- invalid candle volume: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/14f6872f2b0b68e1.
Report an issue: GitHub.