{"record":{"id":"bb1a5a12ec694ae9","repo":"nautechsystems/nautilus_trader","slug":"seconds-timestamp-should-be-within-valid-range","errorCode":null,"errorMessage":"seconds timestamp should be within valid range","messagePattern":"seconds timestamp should be within valid range","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/common/src/generators/client_order_id.rs","lineNumber":60,"sourceCode":"            + \"-\".len()\n    } else {\n        \"O\".len() + DATETIME_TAG_COMPACT_LEN + trader_tag.len() + strategy_tag.len()\n    }\n}\n\n/// Slow path across second boundaries: rebuilds the fixed prefix directly in the output buffer.\nfn write_fixed_prefix(\n    buf: &mut String,\n    trader_tag: &str,\n    strategy_tag: &str,\n    use_hyphens: bool,\n    epoch_second: u64,\n) {\n    let now_utc = Offset::UTC.to_datetime(\n        Timestamp::from_second(\n            i64::try_from(epoch_second).expect(\"seconds timestamp should fit i64\"),\n        )\n        .expect(\"seconds timestamp should be within valid range\"),\n    );\n\n    buf.clear();\n\n    if use_hyphens {\n        write!(\n            buf,\n            \"O-{:04}{:02}{:02}-{:02}{:02}{:02}-{trader_tag}-{strategy_tag}-\",\n            now_utc.year(),\n            now_utc.month(),\n            now_utc.day(),\n            now_utc.hour(),\n            now_utc.minute(),\n            now_utc.second(),\n        )\n        .expect(\"writing to String should not fail\");\n    } else {\n        write!(","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/common/src/generators/client_order_id.rs#L42-L78","documentation":"After converting epoch seconds to i64, the generator passes them to jiff's Timestamp::from_second, which panics here when the value is outside jiff's supported range (roughly years -9999..9999). A valid i64 second count far beyond that range (or negative pre-epoch values from a broken clock) triggers the panic.","triggerScenarios":"Calling write_fixed_prefix (via refresh_fixed_prefix) with an epoch_second whose i64 conversion succeeds but whose value lies outside Timestamp::from_second's supported range (e.g. i64::MAX seconds, or a u64-wrapped/negative-corrupted clock value).","commonSituations":"Broken system clocks; mocks/fuzz tests with extreme timestamps; corrupted u64 time sources overflowing after conversion.","solutions":["Sanity-check the epoch second (e.g. within a plausible window around now) before formatting","Fix the clock or mock supplying the extreme timestamp","Use a checked fallback: Timestamp::from_second(sec).unwrap_or(Timestamp::NOW) if a degraded ID prefix is acceptable","For tests, restrict generated timestamps to jiff's supported range"],"exampleFix":"// before\nTimestamp::from_second(\n    i64::try_from(epoch_second).expect(\"seconds timestamp should fit i64\"),\n)\n.expect(\"seconds timestamp should be within valid range\")\n// after\nlet ts = Timestamp::from_second(sec)\n    .unwrap_or(Timestamp::NOW);","handlingStrategy":"validation","validationCode":"fn within_jiff_range(sec: u64) -> bool {\n    let s = i64::try_from(sec).unwrap_or(i64::MAX);\n    (-377_705_023_201..=253_402_300_799).contains(&s)\n}","typeGuard":null,"tryCatchPattern":"// Use a checked conversion with fallback\nlet ts = Timestamp::from_second(sec as i64)\n    .unwrap_or(Timestamp::NOW);","preventionTips":["Validate timestamps are within jiff's supported year range before formatting","Monitor system clock sanity (NTP, RTC battery)","Clamp extreme values in test/fuzz generators"],"tags":["rust","panic","timestamp","clock"],"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-14T05:17:10.506Z"}