nautechsystems/nautilus_trader · error

event_slug_builder.interval_mins must be positive

Error message

event_slug_builder.interval_mins must be positive

What it means

The Polymarket up/down event slug builder requires a strictly positive interval_mins because it computes period boundaries from it. A zero value is rejected up front since it would produce invalid/degenerate slugs.

Source

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

impl PolymarketUpDownEventSlugConfig {
    /// Builds event slugs using the current system time.
    ///
    /// # Errors
    ///
    /// Returns an error if the interval or period count is zero, all assets are
    /// blank, or the configured offset resolves before the Unix epoch.
    pub fn build_event_slugs(&self) -> anyhow::Result<Vec<String>> {
        let now = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .map_err(|e| anyhow::anyhow!("system clock before Unix epoch: {e}"))?
            .as_secs();
        self.build_event_slugs_at_unix_secs(now)
    }

    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);

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Set event_slug_builder.interval_mins to a positive value (e.g. 60 for hourly updown markets)
  2. Validate the config at deserialization time so zero intervals are rejected early
  3. Check the config source (TOML/env) for a missing or zero default

Example fix

// before
[event_slug_builder]
interval_mins = 0
// after
[event_slug_builder]
interval_mins = 60
Defensive patterns

Strategy: validation

Validate before calling

assert!(cfg.event_slug_builder.interval_mins > 0, "interval_mins must be positive");

Try / catch

match builder.build_event_slugs() {
    Ok(slugs) => use(slugs),
    Err(e) => { log::error!("slug config invalid: {e}"); return Err(e); }
}

Prevention

When it happens

Trigger: Constructing an EventSlugBuilder config (e.g. for CryptoUpdownSeries) with interval_mins = 0 and calling build_event_slugs (via build_event_slugs_at_unix_secs).

Common situations: Config loaded from TOML/env with a zero or unset interval; mistyping interval in minutes as seconds or fraction truncated to 0.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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