nautechsystems/nautilus_trader · error
Failed to parse `tick_sz` '{}' for {}: {e}
Error message
Failed to parse `tick_sz` '{}' for {}: {e} What it means
parse_spread_instrument parses the definition's tick_sz string into a Price to form the price increment. If tick_sz is empty or not a valid price string, the error is raised naming the value and sprd_id.
Source
Thrown at crates/adapters/okx/src/common/parse.rs:1674
Currency::get_or_create_crypto_with_context(definition.base_ccy, Some(&context));
let quote_currency =
Currency::get_or_create_crypto_with_context(definition.quote_ccy, Some(&context));
let settlement_currency = spread_settlement_currency(definition, underlying, quote_currency);
let is_inverse = matches!(definition.sprd_type, OKXSpreadType::Inverse);
let activation_ns = definition
.list_time
.map(parse_millisecond_timestamp)
.ok_or_else(|| anyhow::anyhow!("`list_time` is required for {}", definition.sprd_id))?;
let expiration_ns = definition
.exp_time
.map(parse_millisecond_timestamp)
.unwrap_or_default();
let ts_event = definition
.u_time
.map_or(ts_init, parse_millisecond_timestamp);
let price_increment = Price::from_str(&definition.tick_sz).map_err(|e| {
anyhow::anyhow!(
"Failed to parse `tick_sz` '{}' for {}: {e}",
definition.tick_sz,
definition.sprd_id
)
})?;
let size_increment = Quantity::from_str(&definition.lot_sz).map_err(|e| {
anyhow::anyhow!(
"Failed to parse `lot_sz` '{}' for {}: {e}",
definition.lot_sz,
definition.sprd_id
)
})?;
let min_quantity = if definition.min_sz.is_empty() {
None
} else {
Some(Quantity::from_str(&definition.min_sz).map_err(|e| {
anyhow::anyhow!(
"Failed to parse `min_sz` '{}' for {}: {e}",View on GitHub (pinned to 18893faf8b)
Solutions
- Print the raw definition and verify tick_sz is a valid non-empty numeric string
- Re-fetch instruments from OKX /sprd/instruments to replace the bad definition
- Add a pre-parse guard treating empty tick_sz as an error with a clear message
- Check for serde field-name/casing mismatches leaving tick_sz unset
Defensive patterns
Strategy: validation
Validate before calling
fn tick_sz_valid(def: &OKXSpreadInstrument) -> bool {
!def.tick_sz.is_empty() && def.tick_sz.parse::<rust_decimal::Decimal>().is_ok()
} Try / catch
let price_increment = match parse_spread_instrument(&definition, ts_init) {
Ok(inst) => inst,
Err(e) => { tracing::error!("tick_sz/lot_sz parse failed for {}: {e:#}", definition.sprd_id); return; }
}; Prevention
- Check serde rename attributes so tickSz maps to tick_sz
- Re-fetch definitions from the live endpoint rather than trusting stale caches
- Add empty-string pre-checks with descriptive errors
When it happens
Trigger: Calling parse_spread_instrument when the spread definition's tick_sz is empty, malformed (e.g. contains units), or uses an unparseable numeric representation.
Common situations: Missing or truncated fields in cached/manual spread definitions; OKX payload changes; fixture typos such as tick_sz vs tickSz casing.
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Unknown position currency '{pos_ccy}' for instrument {instru
- Invalid timeframe for `BarSpecification`, was {timeframe}
- price precision {precision} exceeds maximum {MAX_DECIMALS}
- invalid price `{value}`: {e}
- invalid price `{value}` at precision {precision}: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/534b423c93217eee.
Report an issue: GitHub.