nautechsystems/nautilus_trader · error
event_slug_builder offset resolves before the Unix epoch
Error message
event_slug_builder offset resolves before the Unix epoch
What it means
Slug timestamps are computed as period_start + (start_offset_periods + period) * period_secs using i128 arithmetic; if the result is negative, the computed period starts before the Unix epoch and no valid Polymarket slug exists, so the builder bails.
Source
Thrown at crates/adapters/polymarket/src/config.rs:138
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
));
}
}
Ok(slugs)
}
fn normalized_assets(&self) -> Vec<String> {
let mut assets = Vec::new();
for asset in &self.assets {
let asset = asset.trim().to_ascii_lowercase();View on GitHub (pinned to 18893faf8b)
Solutions
- Set start_offset_periods to a non-negative (or only slightly negative) value so period_start + offset*period_secs >= 0
- Clamp or validate start_offset_periods in config parsing against period_secs
- If using a fixed test clock, ensure the base timestamp is comfortably after the epoch
Example fix
// before start_offset_periods = -10_000_000_000 // underflows below epoch // after start_offset_periods = -1 // only look back one period
Defensive patterns
Strategy: validation
Validate before calling
let period_secs = interval_mins * 60; let first = i128::from(now) + i128::from(start_offset_periods) * i128::from(period_secs); assert!(first >= 0, "offset resolves before Unix epoch");
Try / catch
match builder.build_event_slugs() {
Ok(slugs) => use(slugs),
Err(e) => { log::error!("slug offset invalid: {e}"); return Err(e); }
} Prevention
- Bound |start_offset_periods| to a small window (e.g. <= 10)
- Never use unix_secs near 0 in production or fixtures
- Validate offsets against period_secs at config load
When it happens
Trigger: A large negative start_offset_periods combined with a small now/period_start pushes the first period timestamp below 0 (only possible with synthetic/test clocks or extreme negative offsets, since period_start is typically current Unix time).
Common situations: Test harnesses with unix_secs near 0; config carrying a very negative start_offset_periods after a mistaken unit conversion.
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
- event_slug_builder.interval_mins must be positive
- event_slug_builder.periods must be positive
- event_slug_builder.assets must include at least one non-empt
- Polymarket {signature_type:?} signature type requires a fund
- PolymarketFeeModel requires fee schedule exponent 1, was {}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/a259c75379152d43.
Report an issue: GitHub.