nautechsystems/nautilus_trader · error

event_slug_builder.periods must be positive

Error message

event_slug_builder.periods must be positive

What it means

build_event_slugs_at_unix_secs rejects the up/down event slug configuration because the periods field of event_slug_builder is zero or otherwise non-positive; a positive count is required to generate the trailing window of period slugs.

Source

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

    /// # 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);
        let mut slugs = Vec::new();

        for period in 0..self.periods {
            let period_offset = i128::from(self.start_offset_periods) + i128::from(period);

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Set event_slug_builder.periods to a positive integer equal to the number of consecutive periods to cover
  2. Validate config at load time to catch zero periods before runtime
  3. Review how periods is computed (e.g. hours/day ÷ interval_mins) to avoid rounding to 0

Example fix

// before
[event_slug_builder]
periods = 0
// after
[event_slug_builder]
periods = 24 # one day of 60m periods
Defensive patterns

Strategy: validation

Validate before calling

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

Try / catch

if let Err(e) = builder.build_event_slugs() {
    log::error!("slug config invalid: {e}");
    return Err(e);
}

Prevention

When it happens

Trigger: Building event slugs with an EventSlugBuilder configured with periods = 0.

Common situations: Config file with periods omitted/zero; programmatic config construction forgetting to set periods; misinterpreting periods as inclusive end index.

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