nautechsystems/nautilus_trader · error

PolymarketRtdsCryptoTwap metadata['window_seconds'] must be

Error message

PolymarketRtdsCryptoTwap metadata['window_seconds'] must be 30 or 60, received {other}

What it means

TryFrom<u64> for RtdsCryptoTwapWindow: the RTDS crypto TWAP metadata window_seconds is neither 30 nor 60, the only TWAP windows Polymarket's real-time stream publishes, so the metadata cannot be deserialized into a valid topic.

Source

Thrown at crates/adapters/polymarket/src/rtds.rs:253

        }
    }

    const fn topic(self) -> RtdsTopic {
        match self {
            Self::ThirtySeconds => RtdsTopic::CryptoPricesTwapThirty,
            Self::SixtySeconds => RtdsTopic::CryptoPricesTwapSixty,
        }
    }
}

impl TryFrom<u64> for RtdsCryptoTwapWindow {
    type Error = anyhow::Error;

    fn try_from(value: u64) -> Result<Self, Self::Error> {
        match value {
            30 => Ok(Self::ThirtySeconds),
            60 => Ok(Self::SixtySeconds),
            other => anyhow::bail!(
                "PolymarketRtdsCryptoTwap metadata['window_seconds'] must be 30 or 60, received {other}"
            ),
        }
    }
}

#[derive(Clone, Copy)]
enum TimestampGuard {
    // Snapshots can replay, so drop points at or before the high-water mark.
    Snapshot,
    // Live updates never replay, so drop only strictly-older points.
    Live,
}

#[derive(Clone, Copy, Debug)]
pub(crate) enum ReconcileReason {
    DesiredChanged,
    EnsureConnected,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Upgrade the nautilus_polymarket adapter to a version supporting the advertised window
  2. Restrict subscriptions to 30s/60s TWAP channels
  3. Validate metadata['window_seconds'] in (30, 60) before constructing the TWAP type

Example fix

// before
let window = PolymarketRtdsCryptoTwap::try_from(15u64)?; // panics/bails
// after
let window = PolymarketRtdsCryptoTwap::try_from(30u64)?;
Defensive patterns

Strategy: type-guard

Validate before calling

fn supported_twap_window(w: u64) -> bool { w == 30 || w == 60 }

Type guard

fn as_twap_window(w: u64) -> Option<u64> {
    matches!(w, 30 | 60).then_some(w)
}

Try / catch

match PolymarketRtdsCryptoTwap::try_from(window_seconds) {
    Err(e) => { log::error!("unsupported TWAP window: {e}"); return; }
    Ok(w) => w,
}

Prevention

When it happens

Trigger: RTDS metadata advertises a window_seconds value other than 30 or 60 (new interval added upstream, corrupted metadata, or misconfigured subscription), and the conversion runs.

Common situations: Polymarket adding a new TWAP interval before this adapter supports it; hand-edited subscription config; version drift between the adapter and the live RTDS API.

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/f32a4250894d5ab4. Report an issue: GitHub.