nautechsystems/nautilus_trader · error
{field} {value} is not exactly representable with price prec
Error message
{field} {value} is not exactly representable with price precision {precision} What it means
Domain Price values have fixed precision. After converting with Price::from_decimal_dp, the code checks the round-trip is exact; this error fires when the price decimal has more fractional digits than the configured price precision (e.g. 0.525 with precision 2).
Source
Thrown at crates/adapters/polymarket/src/execution/reconciliation.rs:300
let quantity = Quantity::from_decimal_dp(value, precision).with_context(|| {
format!("failed to represent {field} {value} with quantity precision {precision}")
})?;
anyhow::ensure!(
quantity.as_decimal() == value,
"{field} {value} is not exactly representable with quantity precision {precision}",
);
Ok(())
}
fn validate_price_evidence(value: Decimal, precision: u8, field: &str) -> anyhow::Result<()> {
anyhow::ensure!(
value > Decimal::ZERO && value < Decimal::ONE,
"{field} {value} must be greater than zero and less than one",
);
let price = Price::from_decimal_dp(value, precision).with_context(|| {
format!("failed to represent {field} {value} with price precision {precision}")
})?;
anyhow::ensure!(
price.as_decimal() == value,
"{field} {value} is not exactly representable with price precision {precision}",
);
Ok(())
}
fn validate_historical_price_evidence(value: Decimal, field: &str) -> anyhow::Result<Price> {
anyhow::ensure!(
value > Decimal::ZERO && value < Decimal::ONE,
"{field} {value} must be greater than zero and less than one",
);
let evidence = value.normalize();
anyhow::ensure!(
evidence.scale() <= u32::from(FIXED_PRECISION),
"historical {field} {value} exceeds the maximum representable price precision of {FIXED_PRECISION} decimals",
);
let price = Price::from_decimal(evidence)
.with_context(|| format!("failed to represent historical {field} {value}"))?;View on GitHub (pinned to 18893faf8b)
Solutions
- Check the market's tick_size from Polymarket metadata and set the instrument price precision to match (e.g. 3 for 0.001 ticks).
- Refetch market metadata — Polymarket can change tick size dynamically during a market's life.
- Parse prices from the provider's string fields with Decimal directly to avoid float noise.
- Round only with explicit confirmation that the venue accepts the rounded tick.
Example fix
// before
let precision = 2u8;
validate_price_evidence(row.price, precision, "price")?;
// after
let precision = u8::try_from(market.tick_size_decimals).expect("tick precision");
validate_price_evidence(row.price, precision, "price")?; Defensive patterns
Strategy: validation
Validate before calling
fn fits_price_precision(p: Decimal, precision: u8) -> bool {
p.fract().scale() <= precision as u32
} Type guard
fn exactly_representable_price(v: Decimal, precision: u8) -> Option<Price> {
Price::from_decimal_dp(v, precision).ok().filter(|p| p.as_decimal() == v)
} Try / catch
match validate_price_evidence(price, precision, "price") {
Ok(()) => (),
Err(e) if e.to_string().contains("representable") => reload_tick_size_and_retry(&market_id)?,
Err(e) => return Err(e),
} Prevention
- Derive price precision from the market's tick_size metadata, not a hardcoded constant
- Refetch metadata when Polymarket changes a market's tick size dynamically
- Parse provider price strings directly into Decimal to avoid float artifacts
When it happens
Trigger: validate_price_evidence (from validate_order_row_values) gets a Decimal whose fractional scale exceeds the instrument's price precision, so price.as_decimal() != value.
Common situations: Polymarket tick sizes of 0.001 while instrument price precision is configured as 2; provider price strings with more decimals after a tick-size change; parsing artifacts adding float noise.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- price precision {precision} exceeds maximum {MAX_DECIMALS}
- AX {field} scale must not exceed 26 for exact percent conver
- invalid {name} price: {e}
- Failed to create avg_px price: {e}
- price decimals {decimals} exceeds maximum {MAX_DECIMALS}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/614bfd909eee7168.
Report an issue: GitHub.