nautechsystems/nautilus_trader · error · anyhow::Error
Invalid timestamp '{ts}': {e}
Error message
Invalid timestamp '{ts}': {e} What it means
parse_timestamp_ms converts a millisecond epoch string from Polymarket messages into a UnixNanos value. If the string cannot be parsed as a u64 (non-numeric, empty, or containing invalid characters), the function wraps the std parse error in an anyhow error with the offending input.
Source
Thrown at crates/adapters/polymarket/src/websocket/parse.rs:47
types::{Price, Quantity},
};
use rust_decimal::Decimal;
use serde::Serialize;
use super::messages::{
PolymarketBestBidAsk, PolymarketBookLevel, PolymarketBookSnapshot, PolymarketQuote,
PolymarketTrade,
};
use crate::common::{
enums::PolymarketOrderSide,
parse::{determine_trade_id, parse_decimal_exact},
};
/// Parses a millisecond epoch timestamp string into [`UnixNanos`].
pub fn parse_timestamp_ms(ts: &str) -> anyhow::Result<UnixNanos> {
let ms: u64 = ts
.parse()
.map_err(|e| anyhow::anyhow!("Invalid timestamp '{ts}': {e}"))?;
let ns = ms
.checked_mul(NANOSECONDS_IN_MILLISECOND)
.ok_or_else(|| anyhow::anyhow!("Timestamp overflow for '{ts}'"))?;
Ok(UnixNanos::from(ns))
}
pub(crate) fn parse_price(s: &str, precision: u8) -> CorrectnessResult<Price> {
let value = parse_decimal_exact(s).map_err(|e| CorrectnessError::PredicateViolation {
message: format!("Invalid price '{s}': {e}"),
})?;
Price::from_decimal_dp(value, precision)
}
pub(crate) fn parse_quantity(s: &str, precision: u8) -> CorrectnessResult<Quantity> {
let value = parse_decimal_exact(s).map_err(|e| CorrectnessError::PredicateViolation {
message: format!("Invalid quantity '{s}': {e}"),
})?;
Quantity::from_decimal_dp(value, precision)View on GitHub (pinned to 18893faf8b)
Solutions
- Log/inspect the ts string from the error message — it names the exact invalid value
- Convert ISO-8601 timestamps to epoch milliseconds before calling (e.g. via chrono)
- Truncate or reject float timestamps: parse as f64 then cast, or strip fractional part
- Update the adapter parsing if Polymarket changed the field format
Example fix
// before: parse_timestamp_ms("2024-01-15T10:00:00Z") fails
let ts = parse_timestamp_ms(msg.timestamp)?;
// after: normalize ISO timestamps to epoch millis first
let ms = if msg.timestamp.contains('-') {
chrono::DateTime::parse_from_rfc3339(&msg.timestamp)
.map_err(|e| anyhow::anyhow!("bad ts: {e}"))?
.timestamp_millis()
.to_string()
} else {
msg.timestamp.clone()
};
let ts = parse_timestamp_ms(&ms)?; Defensive patterns
Strategy: validation
Validate before calling
fn is_epoch_millis(s: &str) -> bool {
!s.is_empty() && s.bytes().all(|b| b.is_ascii_digit()) && s.len() <= 13
} Type guard
fn as_epoch_millis(raw: &str) -> Option<u64> { raw.parse::<u64>().ok() } Try / catch
match parse_timestamp_ms(ts) {
Ok(nanos) => /* proceed */,
Err(e) if e.to_string().contains("Invalid timestamp") => {
log::warn!("dropping message with bad timestamp: {e}");
}
Err(e) => return Err(e),
} Prevention
- Pass epoch milliseconds, never ISO-8601 strings or floats
- Normalize timestamp format at message-decode time
- Check the venue schema before assuming the timestamp format
When it happens
Trigger: Calling parse_timestamp_ms with a string that is not a valid u64: empty string, "2024-01-15T10:00:00Z" (ISO format), "1699999999999.5" (float), or a field that is null/missing stringified.
Common situations: Polymarket changing the timestamp field format; passing an ISO-8601 datetime instead of epoch millis; unit tests feeding mock payloads with wrong timestamp encodings.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Invalid execution time format: {time_str}
- Execution timestamp '{time_str}' is non-existent in timezone
- Negative nanosecond timestamp from: {timestamp}
- event_slug_builder offset resolves before the Unix epoch
- Expected 2 token IDs, received {}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/bcaf1d6e16629481.
Report an issue: GitHub.