BoundaryML/baml · error
system clock is set before the UNIX epoch
Error message
system clock is set before the UNIX epoch
What it means
The WASM sys-op now() returns wall-clock nanoseconds since the UNIX epoch per the Instant.now() contract. If web_time::SystemTime::now() reports a time before the epoch, duration_since returns Err and the code panics with 'system clock is set before the UNIX epoch'. The library intentionally panics because a pre-epoch clock cannot be represented as a valid Instant.
Solutions
- Fix the host system clock (sync via NTP) so it reports a post-epoch time
- In tests, mock time with values after the UNIX epoch
- Wrap time sys-op calls to detect obviously invalid clocks before invoking now()
- Report/raise an environment error instead of calling now() when the clock is known bad
Example fix
// before
const t = sys.now(); // panics if clock < epoch
// after
if (Date.now() < 0) throw new Error('system clock before UNIX epoch');
const t = sys.now(); Defensive patterns
Strategy: validation
Validate before calling
if (Date.now() <= 0) throw new Error('Host system clock is before the UNIX epoch; fix system time'); Prevention
- Sync host clocks with NTP, especially in VMs/containers
- Never mock system time with pre-epoch values in tests
- Check clock sanity at app startup before time-dependent calls
- Avoid calling Instant.now() on environments known to have unset RTCs
When it happens
Trigger: Calling Instant.now() (the time sys-op) while the host/browser reports a system clock earlier than 1970-01-01T00:00:00Z.
Common situations: VMs or embedded devices with unset RTC clocks booting at epoch 0, misconfigured NTP/timezones resetting system time, or test environments faking Date/SystemTime with negative offsets.
Understand the failure class
Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.
Related errors
- BAML internal error - credential provider bridges not…
- Base64 decode error
- {}: {error}
- Expr function error
- failed to create base http client for WASM
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/95dcc796948fe52b.
Report an issue: GitHub.
Appendix: source
Thrown at baml_language/crates/bridge_wasm/src/wasm_time.rs:111
.map_err(|e| other("Temporal.ZonedDateTime is not a constructor", &e))?;
let args = Array::of2(epoch_ns, &JsValue::from_str(timezone));
Ok(Reflect::construct(&ctor, &args)
.ok()
.and_then(|v| v.dyn_into::<Object>().ok()))
}
impl io::IoClassTimeInstant for WasmTime {
fn now(
&self,
_heap: &Arc<BexHeap>,
_call_id: CallId,
_ctx: &SysOpContext,
) -> SysOpOutput<owned::time::Instant> {
// Wall-clock time as nanoseconds since the UNIX epoch. Per the
// `Instant.now()` contract, an unavailable/pre-epoch clock panics.
let nanos = web_time::SystemTime::now()
.duration_since(web_time::UNIX_EPOCH)
.expect("system clock is set before the UNIX epoch")
.as_nanos();
SysOpOutput::ok(owned::time::Instant {
_nanoseconds: Arc::new(num_bigint::BigInt::from(nanos)),
})
}
}
impl io::IoNamespaceTime for WasmTime {
fn system_timezone(
&self,
_heap: &Arc<BexHeap>,
_call_id: CallId,
_ctx: &SysOpContext,
) -> SysOpOutput<String> {
// Temporal.Now.timeZoneId()
let result: Result<String, VmRustFnError> = (|| {
let temporal = temporal()?;
let now = Reflect::get(&temporal, &"Now".into())View on GitHub (pinned to bd85ce9dee)