nautechsystems/nautilus_trader · error
invalid market-buy price {price}: must satisfy 0 < price < 1
Error message
invalid market-buy price {price}: must satisfy 0 < price < 1 for fee adjustment What it means
adjust_market_buy_amount applies Polymarket's fee curve to a market-buy amount, and that math is only defined for prices strictly between 0 and 1 (a binary-market outcome probability). The function bails out when the supplied price is zero, negative, or >= 1, since fees at such prices are meaningless or non-finite.
Source
Thrown at crates/adapters/polymarket/src/execution/parse.rs:518
/// `price` must be strictly inside `(0, 1)`. The SDK relies on its
/// order-builder pipeline to enforce this. Because [`adjust_market_buy_amount`]
/// is public, it repeats the precondition here.
///
/// # Errors
///
/// Returns an error if `price` is outside the open `(0, 1)` interval, or if
/// amount or balance is non-positive, a fee input is negative, arithmetic overflows,
/// or the adjusted amount truncates to zero.
pub fn adjust_market_buy_amount(
amount: Decimal,
user_pusd_balance: Decimal,
price: Decimal,
fee_rate: Decimal,
fee_exponent: Decimal,
builder_taker_fee_rate: Decimal,
) -> anyhow::Result<Decimal> {
if price <= Decimal::ZERO || price >= Decimal::ONE {
anyhow::bail!(
"invalid market-buy price {price}: must satisfy 0 < price < 1 for fee adjustment",
);
}
let platform_fee_rate = fee_curve_rate(fee_rate, price, fee_exponent)?;
anyhow::ensure!(amount > Decimal::ZERO, "market-buy amount must be positive");
anyhow::ensure!(
user_pusd_balance > Decimal::ZERO,
"market-buy balance must be positive"
);
anyhow::ensure!(
builder_taker_fee_rate >= Decimal::ZERO,
"builder fee rate must be non-negative"
);
let platform_fee = amount
.checked_div(price)
.and_then(|shares| shares.checked_mul(platform_fee_rate))View on GitHub (pinned to 18893faf8b)
Solutions
- Verify the price is a Decimal in (0, 1) before calling; divide by 100 if it came from a percentage source.
- Check the source of the price (book level, manual input) — reject empty or degenerate books earlier via calculate_market_price.
- For markets priced at ~0 or ~1, treat the order as invalid and surface a user-facing validation error instead of calling the fee adjustment.
- Add a unit test pinning boundary behavior at price=0, 1, and just inside the range.
Example fix
// before let price = Decimal::from(55); // percent, not decimal let amount = adjust_market_buy_amount(balance, price, fee_rate, fee_exponent, builder_taker_fee_rate)?; // after let price = Decimal::from(55) / Decimal::from(100); // 0.55 anyhow::ensure!(price > Decimal::ZERO && price < Decimal::ONE, "price must be in (0, 1)"); let amount = adjust_market_buy_amount(balance, price, fee_rate, fee_exponent, builder_taker_fee_rate)?;
Defensive patterns
Strategy: validation
Validate before calling
if price <= Decimal::ZERO || price >= Decimal::ONE {
return Err(format!("price {price} outside (0,1); check percent-vs-decimal conversion"));
} Type guard
fn is_valid_market_price(p: &Decimal) -> bool {
*p > Decimal::ZERO && *p < Decimal::ONE
} Prevention
- Always represent prices as decimals in (0,1), never percentages
- Validate prices at the API boundary before fee math
- Test boundary conditions price=0 and price=1 in unit tests
- Derive prices from calculate_market_price so books are validated first
When it happens
Trigger: Calling adjust_market_buy_amount (directly or via order building in submit-market flows) with price <= 0 or price >= 1 — typically a price derived from a stale/empty book, a percentage vs decimal unit mistake (e.g. 55 instead of 0.55), or a price of exactly 1.0 for a fully-resolved market.
Common situations: Unit-conversion bugs (feeding percent-scaled prices), best-ask fetched from a degenerate book, or submitting market buys on markets at the resolution boundary where the top-of-book price is 1.
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
- user_pusd_balance {user_pusd_balance} too small to cover fee
- Polymarket market BUY amount {} pUSD truncates to zero at {L
- PolymarketFeeModel requires a binary option instrument
- Liquidity side not set
- PolymarketFeeModel requires a fill price in [0, 1]
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/6eece8e1ebf86dd5.
Report an issue: GitHub.