nautechsystems/nautilus_trader · error
Failed to parse tick size '{new_tick_size}': {e}
Error message
Failed to parse tick size '{new_tick_size}': {e} What it means
rebuild_instrument_with_tick_size parses the new tick size string with parse_decimal_exact before rebuilding the BinaryOption's price bounds. This error is thrown when the tick-size string from a Polymarket market message is not a valid exact decimal.
Source
Thrown at crates/adapters/polymarket/src/http/parse.rs:279
.collect()
}
/// Rebuilds an instrument with a new active tick size and canonical price precision.
///
/// All other fields are preserved from `existing`. Returns a new `InstrumentAny`.
pub fn rebuild_instrument_with_tick_size(
existing: &InstrumentAny,
new_tick_size: &str,
ts_event: UnixNanos,
ts_init: UnixNanos,
) -> anyhow::Result<InstrumentAny> {
let bo = match existing {
InstrumentAny::BinaryOption(b) => b,
other => anyhow::bail!("Expected BinaryOption, was {other:?}"),
};
let tick_size = parse_decimal_exact(new_tick_size)
.map_err(|e| anyhow::anyhow!("Failed to parse tick size '{new_tick_size}': {e}"))?;
let (min_price, max_price) = tick_relative_price_bounds(tick_size)?;
let price_increment = min_price;
let rebuilt = BinaryOption::builder()
.instrument_id(bo.id)
.raw_symbol(bo.raw_symbol)
.asset_class(bo.asset_class)
.currency(bo.currency)
.activation_ns(bo.activation_ns)
.expiration_ns(bo.expiration_ns)
.price_precision(POLYMARKET_PRICE_PRECISION)
.size_precision(bo.size_precision)
.price_increment(price_increment)
.size_increment(bo.size_increment)
.maybe_outcome(bo.outcome)
.maybe_description(bo.description)
.maybe_max_quantity(bo.max_quantity)
// min_quantity: see `create_instrument_from_def`View on GitHub (pinned to 18893faf8b)
Solutions
- Log the offending new_tick_size value from the market message.
- Validate/normalize the tick size string before calling rebuild (trim, reject empty, parse as Decimal).
- Skip or defer the instrument rebuild when the tick size is unparseable, and re-sync instruments from the REST snapshot.
Example fix
// before
let tick_size = parse_decimal_exact(new_tick_size)
.map_err(|e| anyhow::anyhow!("Failed to parse tick size '{new_tick_size}': {e}"))?;
// after
let trimmed = new_tick_size.trim();
if trimmed.is_empty() { anyhow::bail!("skip rebuild: empty tick size"); }
let tick_size = parse_decimal_exact(trimmed)
.map_err(|e| anyhow::anyhow!("Failed to parse tick size '{new_tick_size}': {e}"))?; Defensive patterns
Strategy: validation
Validate before calling
fn is_valid_tick_size_str(s: &str) -> bool {
!s.trim().is_empty() && parse_decimal_exact(s.trim()).map(|d| d > Decimal::ZERO).unwrap_or(false)
} Try / catch
match rebuild_instrument_with_tick_size(&instrument, &msg.new_tick_size) {
Ok(updated) => updated,
Err(e) => { warn!("tick size update rejected: {e}"); instrument.clone() }
} Prevention
- Normalize tick size strings (trim, reject empty) before parsing.
- Only accept tick sizes known to be representable at Polymarket price precision.
- Re-sync instruments from REST when a streamed tick size fails to parse.
When it happens
Trigger: handle_market_message receiving a market update whose new_tick_size is empty, non-numeric, or in a format parse_decimal_exact rejects (e.g. scientific notation, thousands separators).
Common situations: Unexpected tick_size values in CLOB market channel updates, venue emitting "0" or blank during market setup, or locale-formatted numbers from a custom feed.
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
- invalid signed E18 integer for {field}: {value}
- Empty book snapshot for {instrument_id}
- invalid {field}='{raw}': {e}
- invalid price `{value}`: {e}
- invalid quantity `{value}`: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/48541d4e1cfb0c34.
Report an issue: GitHub.