From 26de74fd70a48f7c780e25aa14bbd291e71b210a Mon Sep 17 00:00:00 2001 From: Yanhu007 Date: Sun, 12 Apr 2026 14:02:02 +0800 Subject: [PATCH] fix: convert epoch-ms to BigInt before nanosecond multiplication Several OTLP timestamp conversions multiply epoch milliseconds by 1,000,000 before converting to BigInt. Since epoch-ms * 1e6 is ~1.7e18 (exceeding Number.MAX_SAFE_INTEGER ~9e15), this causes IEEE 754 precision loss of ~256ns in ~0.2% of cases. The correct pattern (already used in convertDateToNanoseconds) is: BigInt(date.getTime()) * BigInt(1_000_000) Fixed in: - getNowInNanoseconds() - calculateDurationFromStart() - recordEvent() call in runEngineHandlers Fixes #3292 --- apps/webapp/app/v3/eventRepository/common.server.ts | 4 ++-- apps/webapp/app/v3/runEngineHandlers.server.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/webapp/app/v3/eventRepository/common.server.ts b/apps/webapp/app/v3/eventRepository/common.server.ts index 3ba8a50c7f7..5d5d0e201f1 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; diff --git a/apps/webapp/app/v3/runEngineHandlers.server.ts b/apps/webapp/app/v3/runEngineHandlers.server.ts index 411f91ff75d..aa355cd04dd 100644 --- a/apps/webapp/app/v3/runEngineHandlers.server.ts +++ b/apps/webapp/app/v3/runEngineHandlers.server.ts @@ -428,7 +428,7 @@ export function registerRunEngineEventBusHandlers() { const eventRepository = resolveEventRepositoryForStore(run.taskEventStore); await eventRepository.recordEvent(retryMessage, { - startTime: BigInt(time.getTime() * 1000000), + startTime: BigInt(time.getTime()) * BigInt(1_000_000), taskSlug: run.taskIdentifier, environment, attributes: {