nautechsystems/nautilus_trader · error

limit must be greater than zero

Error message

limit must be greater than zero

What it means

Input validation in the Polymarket data API request_trade_ticks: an explicit limit of 0 was passed. A zero limit would request no trades and produce a meaningless response, so it is rejected before pagination begins.

Source

Thrown at crates/adapters/polymarket/src/http/data_api.rs:411

        condition_id: &str,
        token_id: &str,
        price_precision: u8,
        size_precision: u8,
        start: Option<UnixNanos>,
        end: Option<UnixNanos>,
        limit: Option<u32>,
    ) -> anyhow::Result<Vec<TradeTick>> {
        const PAGE_SIZE: u32 = 500;
        const MAX_OFFSET: u32 = 10_000;

        if let (Some(start), Some(end)) = (start, end)
            && start > end
        {
            anyhow::bail!("start must not be later than end");
        }

        if limit == Some(0) {
            anyhow::bail!("limit must be greater than zero");
        }

        let start_secs = start.map(|value| (value.as_u64() / 1_000_000_000) as i64);
        let end_secs = end.map(|value| (value.as_u64() / 1_000_000_000) as i64);
        let protocol = OffsetProtocol::new(
            "/trades",
            PAGE_SIZE as usize,
            trade_page_fingerprint,
            Some((
                MAX_OFFSET,
                TradeTickStop::VenueOffsetCeiling(OffsetCeilingSource::Local),
            )),
        );
        let reducer = TradeTickReducer {
            rows: Vec::new(),
            instrument_id,
            condition_id: condition_id.to_string(),
            token_id: token_id.to_string(),

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Pass None for limit when you want the API default (page-size driven) behavior.
  2. Clamp or reject non-positive limits at the call site before invoking the API.
  3. Fix the upstream calculation that produced a zero remaining-budget value.

Example fix

// before
let limit = remaining_budget(); // may be Some(0)
api.request_trade_ticks(Some(cid), start, end, limit).await?;
// after
let limit = remaining_budget().filter(|&l| l > 0);
api.request_trade_ticks(Some(cid), start, end, limit).await?;
Defensive patterns

Strategy: validation

Validate before calling

// Rust: normalize limit before calling
fn effective_limit(limit: Option<u32>) -> Option<u32> {
    limit.filter(|&l| l > 0)
}

Type guard

fn positive_limit(limit: Option<u32>) -> Option<NonZeroU32> {
    limit.and_then(NonZeroU32::new)
}

Prevention

When it happens

Trigger: Calling request_trade_ticks with limit == Some(0).

Common situations: Computing a remaining quota or page budget that underflows to 0; passing an unconfigured/default numeric value of 0 instead of leaving limit as None; config parsing turning an unset limit into Some(0).

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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