Skip to content

STRATCONN-4121 - [Customerio] - fix timestamp normalization occurring after isIsoDate gate - #3930

Open
sydneycollins-cio wants to merge 2 commits into
segmentio:mainfrom
sydneycollins-cio:fix/customerio-timestamp-normalize-before-gate
Open

STRATCONN-4121 - [Customerio] - fix timestamp normalization occurring after isIsoDate gate#3930
sydneycollins-cio wants to merge 2 commits into
segmentio:mainfrom
sydneycollins-cio:fix/customerio-timestamp-normalize-before-gate

Conversation

@sydneycollins-cio

Copy link
Copy Markdown
Contributor

Problem

Supersedes PR #3923. Joe Ayoub identified that the fix in #3923 lands one step too late.

In convertAttributeTimestamps, the code calls isIsoDate(value) on the original string before normalizing. isIsoDate ends with !isNaN(Date.parse(value)). In Segment's prod runtime, Date.parse returns NaN for fractional seconds longer than ~5 digits — so a 7-digit timestamp like 2024-08-14T20:36:48.6527521Z fails isIsoDate, never enters the block, and normalization is never reached. Tests in #3923 passed only because local Node accepts long fractions.

Fix

Move normalizeIsoFractionalSeconds to before the isIsoDate gate in convertAttributeTimestamps:

// Before (broken in prod runtime)
if (isIsoDate(value)) {
  ;(clone[key] as unknown) = dayjs(normalizeIsoFractionalSeconds(value)).unix()
}

// After (Joe's fix)
const normalized = normalizeIsoFractionalSeconds(value)
if (isIsoDate(normalized)) {
  ;(clone[key] as unknown) = dayjs(normalized).unix()
}

Same fix applied to convertValidTimestamp. normalizeIsoFractionalSeconds trims fractional seconds to 3 digits — no precision is lost since Unix timestamps are second-level.

Tests

Added mocked Date.parse cases that emulate Segment's prod runtime behavior (reject fractions longer than 5 digits), confirming the fix works in that environment. All 20 tests pass.

…te (STRATCONN-4121)

Joe Ayoub's review of PR segmentio#3923 identified that the fix landed one step too
late: convertAttributeTimestamps called isIsoDate(value) on the original
string, but in Segment's prod runtime Date.parse returns NaN for >5 fractional
digits — so 7-digit timestamps like 2024-08-14T20:36:48.6527521Z never entered
the normalization block.

Fix: normalize before the gate (normalize -> isIsoDate -> dayjs) so the
isIsoDate check sees a valid 3-digit millisecond string regardless of the
original precision.

Also applies normalizeIsoFractionalSeconds to convertValidTimestamp (same
root cause).

Tests: adds mocked Date.parse cases that emulate prod runtime behavior,
confirming the fix works even when Date.parse rejects long fractions.
@joe-ayoub-segment

Copy link
Copy Markdown
Contributor

Thanks @sydneycollins-cio approved to be deployed. Thank you!

@sydneycollins-cio
sydneycollins-cio force-pushed the fix/customerio-timestamp-normalize-before-gate branch from f0e14d2 to b3cce8f Compare August 7, 2026 15:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants