nautechsystems/nautilus_trader · error

Polymarket market BUY amount {} pUSD truncates to zero at {L

Error message

Polymarket market BUY amount {} pUSD truncates to zero at {LOT_SIZE_SCALE} decimal places

What it means

For market BUY orders on Polymarket, amount is denominated in pUSD; it must round to at least one lot (0.01 pUSD) when truncated to LOT_SIZE_SCALE. build_market_order rejects amounts that truncate to zero, because a zero maker amount would produce an invalid order. This protects against tiny/dust buy amounts being submitted to the CLOB.

Source

Thrown at crates/adapters/polymarket/src/execution/order_builder.rs:206

    /// Builds and signs a market order for submission.
    ///
    /// `amount` semantics differ by side:
    /// - BUY: `amount` is pUSD to spend
    /// - SELL: `amount` is shares to sell
    ///
    /// Market orders never set an expiration.
    pub fn build_market_order(
        &self,
        token_id: &str,
        side: PolymarketOrderSide,
        price: Decimal,
        amount: Decimal,
        neg_risk: bool,
        tick_decimals: u32,
    ) -> anyhow::Result<PolymarketOrder> {
        if side == PolymarketOrderSide::Buy && amount.trunc_with_scale(LOT_SIZE_SCALE).is_zero() {
            anyhow::bail!(
                "Polymarket market BUY amount {} pUSD truncates to zero at {LOT_SIZE_SCALE} decimal places",
                amount.normalize(),
            );
        }

        let (maker_amount, taker_amount) =
            compute_market_maker_taker_amounts(price, amount, side, tick_decimals);
        self.build_and_sign(token_id, side, maker_amount, taker_amount, "0", neg_risk)
    }

    /// Computes the Polymarket order ID for a signed CLOB V2 order.
    pub fn expected_order_id(
        &self,
        order: &PolymarketOrder,
        neg_risk: bool,
    ) -> anyhow::Result<VenueOrderId> {
        let hash = order_hash(order, neg_risk)
            .map_err(|e| anyhow::anyhow!("Failed to derive order hash: {e}"))?;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Increase the market BUY amount to at least one lot (0.01 pUSD, practically the exchange minimum)
  2. Clamp or skip orders whose computed amount is below the minimum notional before calling submit
  3. Check upstream sizing/rounding logic that produced the sub-lot amount
  4. If amounts are intentionally tiny, route them through limit orders or batch them

Example fix

// before
let amount = expected_notional * (1.0 - fee_buffer); // may fall below 0.01
client.submit_market_order(instrument, OrderSide::Buy, amount, ...).await?;
// after
let amount = expected_notional * (1.0 - fee_buffer);
if amount.trunc_with_scale(2) >= Decimal::from_str_exact("0.01")? {
    client.submit_market_order(instrument, OrderSide::Buy, amount, ...).await?;
} else {
    log::debug!("skip market BUY: amount {amount} below minimum lot");
}
Defensive patterns

Strategy: validation

Validate before calling

use rust_decimal::Decimal;
const LOT_SIZE_SCALE: u32 = 2;

fn market_buy_amount_ok(amount: Decimal) -> bool {
    !amount.trunc_with_scale(LOT_SIZE_SCALE).is_zero()
}

// call before submit
if !market_buy_amount_ok(amount) {
    // skip or bump the order size
}

Try / catch

match client.submit_market_order(instrument, OrderSide::Buy, amount, ...).await {
    Err(e) if e.to_string().contains("truncates to zero") => {
        warn!("market BUY amount {amount} below minimum lot; order skipped");
    }
    Err(e) => return Err(e),
    Ok(_) => {},
}

Prevention

When it happens

Trigger: Calling build_market_order (via submit_market_order) with side=Buy and an amount in pUSD whose value truncated to 2 decimal places equals zero (e.g. 0.004 pUSD).

Common situations: Strategy computes a position size smaller than the minimum notional; rounding or fee-adjustment shrinks the order amount below 0.01; unit tests with sub-lot amounts; currency conversion leaving fractional dust.

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/fc3525fed7a18fb4. Report an issue: GitHub.