{"record":{"id":"a259c75379152d43","repo":"nautechsystems/nautilus_trader","slug":"event-slug-builder-offset-resolves-before-the-unix","errorCode":null,"errorMessage":"event_slug_builder offset resolves before the Unix epoch","messagePattern":"event_slug_builder offset resolves before the Unix epoch","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/polymarket/src/config.rs","lineNumber":138,"sourceCode":"        let assets = self.normalized_assets();\n        if assets.is_empty() {\n            anyhow::bail!(\"event_slug_builder.assets must include at least one non-empty asset\");\n        }\n\n        let period_secs = self\n            .interval_mins\n            .checked_mul(60)\n            .ok_or_else(|| anyhow::anyhow!(\"event_slug_builder.interval_mins is too large\"))?;\n        let period_start = (unix_secs / period_secs) * period_secs;\n        let period_secs = i128::from(period_secs);\n        let period_start = i128::from(period_start);\n        let mut slugs = Vec::new();\n\n        for period in 0..self.periods {\n            let period_offset = i128::from(self.start_offset_periods) + i128::from(period);\n            let timestamp = period_start + period_offset * period_secs;\n            if timestamp < 0 {\n                anyhow::bail!(\"event_slug_builder offset resolves before the Unix epoch\");\n            }\n\n            for asset in &assets {\n                slugs.push(format!(\n                    \"{asset}-updown-{}m-{timestamp}\",\n                    self.interval_mins\n                ));\n            }\n        }\n\n        Ok(slugs)\n    }\n\n    fn normalized_assets(&self) -> Vec<String> {\n        let mut assets = Vec::new();\n\n        for asset in &self.assets {\n            let asset = asset.trim().to_ascii_lowercase();","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/polymarket/src/config.rs#L120-L156","documentation":"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.","triggerScenarios":"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).","commonSituations":"Test harnesses with unix_secs near 0; config carrying a very negative start_offset_periods after a mistaken unit conversion.","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"],"exampleFix":"// before\nstart_offset_periods = -10_000_000_000 // underflows below epoch\n// after\nstart_offset_periods = -1 // only look back one period","handlingStrategy":"validation","validationCode":"let period_secs = interval_mins * 60;\nlet first = i128::from(now) + i128::from(start_offset_periods) * i128::from(period_secs);\nassert!(first >= 0, \"offset resolves before Unix epoch\");","typeGuard":null,"tryCatchPattern":"match builder.build_event_slugs() {\n    Ok(slugs) => use(slugs),\n    Err(e) => { log::error!(\"slug offset invalid: {e}\"); return Err(e); }\n}","preventionTips":["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"],"tags":["polymarket","config","timestamp","validation"],"backgroundTag":"value-out-of-range","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}