nautechsystems/nautilus_trader · error · anyhow::Error

event_slug_builder.interval_mins is too large

Error message

event_slug_builder.interval_mins is too large

What it means

build_event_slugs_at_unix_secs computes the period length as interval_mins * 60 seconds using checked_mul. This error is thrown when interval_mins is so large that multiplying by 60 overflows u64, meaning the configured interval is nonsensical and no slug grid can be built.

Source

Thrown at crates/adapters/polymarket/src/config.rs:128

    fn build_event_slugs_at_unix_secs(&self, unix_secs: u64) -> anyhow::Result<Vec<String>> {
        if self.interval_mins == 0 {
            anyhow::bail!("event_slug_builder.interval_mins must be positive");
        }

        if self.periods == 0 {
            anyhow::bail!("event_slug_builder.periods must be positive");
        }

        let assets = self.normalized_assets();
        if assets.is_empty() {
            anyhow::bail!("event_slug_builder.assets must include at least one non-empty asset");
        }

        let period_secs = self
            .interval_mins
            .checked_mul(60)
            .ok_or_else(|| anyhow::anyhow!("event_slug_builder.interval_mins is too large"))?;
        let period_start = (unix_secs / period_secs) * period_secs;
        let period_secs = i128::from(period_secs);
        let period_start = i128::from(period_start);
        let mut slugs = Vec::new();

        for period in 0..self.periods {
            let period_offset = i128::from(self.start_offset_periods) + i128::from(period);
            let timestamp = period_start + period_offset * period_secs;
            if timestamp < 0 {
                anyhow::bail!("event_slug_builder offset resolves before the Unix epoch");
            }

            for asset in &assets {
                slugs.push(format!(
                    "{asset}-updown-{}m-{timestamp}",
                    self.interval_mins
                ));
            }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Set interval_mins to a realistic period length (e.g. 1, 5, 15 minutes as Polymarket up/down markets use).
  2. Validate interval_mins bounds in config deserialization/FromStr before constructing the builder.
  3. Trace where the oversized value comes from (env var, JSON config) and fix the source value.
  4. Add a checked constructor returning a config error for intervals beyond a sane maximum.

Example fix

// before: config.json
{"interval_mins": 18446744073709551615}
// after
{"interval_mins": 15}
Defensive patterns

Strategy: validation

Validate before calling

// Rust: bound-check interval_mins before constructing the slug config
const MAX_INTERVAL_MINS: u64 = 525_600; // one year
fn interval_mins_ok(v: u64) -> bool {
    v > 0 && v <= MAX_INTERVAL_MINS
}

Try / catch

match config.build_event_slugs() {
    Ok(slugs) => use(slugs),
    Err(e) if e.to_string().contains("too large") => {
        return Err(ConfigError::InvalidField("interval_mins"));
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Constructing an UpDownEventSlugConfig (PolymarketConfig's slug builder) with an interval_mins value greater than u64::MAX/60 (~3.07e17 minutes) and calling build_event_slugs_at_unix_secs (directly or via build_event_slugs).

Common situations: A typo or bad deserialization placing a huge number (or u64::MAX sentinel) into interval_mins; a config file with garbage values; unit tests probing overflow behavior.

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