From 170c1f3fb086a4409529d8dd9b0b4856b1d16ef7 Mon Sep 17 00:00:00 2001 From: aayushbaluni <73417844+aayushbaluni@users.noreply.github.com> Date: Wed, 15 Apr 2026 15:26:08 +0530 Subject: [PATCH] fix: prevent IEEE 754 precision loss in OTLP nanosecond timestamps Multiplying epoch milliseconds by 1,000,000 before BigInt conversion produces values exceeding Number.MAX_SAFE_INTEGER (~9e15), causing ~256ns precision errors in ~0.2% of timestamps. Convert to BigInt first, then multiply: - getNowInNanoseconds(): BigInt(ms) * BigInt(1_000_000) - calculateDurationFromStart(): same pattern - calculateDurationFromStartJsDate(): same pattern - recordRunDebugLog(): same pattern The correct pattern already existed in convertDateToNanoseconds() in the same file. Fixes #3292 Made-with: Cursor --- apps/webapp/app/v3/eventRepository/common.server.ts | 6 +++--- apps/webapp/app/v3/eventRepository/index.server.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/webapp/app/v3/eventRepository/common.server.ts b/apps/webapp/app/v3/eventRepository/common.server.ts index 3ba8a50c7f7..d5f88e8e89e 100644 --- a/apps/webapp/app/v3/eventRepository/common.server.ts +++ b/apps/webapp/app/v3/eventRepository/common.server.ts @@ -21,7 +21,7 @@ export function extractContextFromCarrier(carrier: Record) { } export function getNowInNanoseconds(): bigint { - return BigInt(new Date().getTime() * 1_000_000); + return BigInt(new Date().getTime()) * BigInt(1_000_000); } export function getDateFromNanoseconds(nanoseconds: bigint): Date { @@ -35,7 +35,7 @@ export function calculateDurationFromStart( ) { const $endtime = typeof endTime === "string" ? new Date(endTime) : endTime; - const duration = Number(BigInt($endtime.getTime() * 1_000_000) - startTime); + const duration = Number(BigInt($endtime.getTime()) * BigInt(1_000_000) - startTime); if (minimumDuration && duration < minimumDuration) { return minimumDuration; @@ -47,7 +47,7 @@ export function calculateDurationFromStart( export function calculateDurationFromStartJsDate(startTime: Date, endTime: Date = new Date()) { const $endtime = typeof endTime === "string" ? new Date(endTime) : endTime; - return ($endtime.getTime() - startTime.getTime()) * 1_000_000; + return Number(BigInt($endtime.getTime() - startTime.getTime()) * BigInt(1_000_000)); } export function convertDateToNanoseconds(date: Date): bigint { diff --git a/apps/webapp/app/v3/eventRepository/index.server.ts b/apps/webapp/app/v3/eventRepository/index.server.ts index 70ea6440321..edc0280baf2 100644 --- a/apps/webapp/app/v3/eventRepository/index.server.ts +++ b/apps/webapp/app/v3/eventRepository/index.server.ts @@ -215,7 +215,7 @@ async function recordRunEvent( runId: foundRun.friendlyId, ...attributes, }, - startTime: BigInt((startTime?.getTime() ?? Date.now()) * 1_000_000), + startTime: BigInt(startTime?.getTime() ?? Date.now()) * BigInt(1_000_000), ...optionsRest, });