fix: serialize an Invalid Date instead of throwing#24
Merged
Conversation
`Date.prototype.toISOString()` throws a RangeError on an Invalid Date
(`new Date(NaN)`), so `serialize` (and the `/json` `stringify`) crashed
on a value that native `structuredClone` clones without issue:
structuredClone(new Date(NaN)); // Invalid Date, preserved
deserialize(serialize(new Date(NaN))); // RangeError: Invalid time value
Store an empty string for an Invalid Date. It is JSON-safe (so the `/json`
path round-trips too) and `new Date('')` revives back to an Invalid Date,
matching the deserialize side, which already does `new Date(value)`.
WebReflection
approved these changes
Jun 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
serialize(and the/jsonstringify) throws on an Invalid Date, even though nativestructuredClone— the API this package ponyfills — clones it without issue:An Invalid Date is a legitimate value (e.g. the result of
new Date('not a date')), so any object graph that happens to contain one crashes the clone. The README documents no Invalid-Date caveat (the only stated limitation is unsupported array elements becomingnull).Cause
Date.prototype.toISOString()throws aRangeErrorwhen the date's time value isNaN, and theDATEcase calls it unconditionally:The deserialize side already handles it: it does
new Date(value), which faithfully revives an Invalid Date.Fix
Store an empty string for an Invalid Date:
EMPTY('') is chosen deliberately overNaN/getTime(): it is JSON-safe, so the/jsonpath round-trips too (NaNwould serialize tonull, andnew Date(null)revives to epoch 0), andnew Date('')revives to an Invalid Date — matching the deserialize side. Valid dates are unaffected.Tests
Added round-trip assertions for an Invalid Date on both the record API and the
/jsonAPI. They throw onmainand pass with the fix; the rest of the suite is unchanged.(The minified
structured-json.jsbrowser bundle is a build artifact regenerated bynpm run build, so it is left out of this diff.)