You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BUG]: NaT inside a datetime64 array serializes as the string "NaT" instead of null #5829
At 38374ac, a NaT inside a datetime64 array serializes as the string "NaT" on both engines. The same missing value as a list element or a scalar becomes null, and from_json reads the string back as data.
plotly.js happens to draw a gap for the string, so a chart looks right. Anything else that reads the figure JSON, such as Dash figure State, gets a string where null belongs.
Screenshots/Video
None: the defect is in the serialized JSON, quoted above.
contract: tests/test_optional/test_utils/test_utils.py:276 already asserts null for pd.NaT inside an object-dtype Series, and :291 asserts "[null]" for [pd.NaT]. The datetime64 dtype of that same Series breaks the promise. The scalar case is tests/test_io/test_to_from_plotly_json.py:265.
The json engine (the auto fallback when orjson is absent) goes through encode_as_numpy at _plotly_utils/utils.py:297, and orjson goes through clean_to_json_compatible at plotly/io/_json.py:517. Both call datetime_as_string unfiltered:
- return numpy.datetime_as_string(obj).tolist()+ return [+ None if s == "NaT" else s+ for s in numpy.datetime_as_string(obj).tolist()+ ]
$ python -I repro.py | grep -E "series|round" # filter at utils.py:297 only
json series -> ['2020-01-01T00:00:00.000000', None]
json round -> ['2020-01-01T00:00:00.000000', None]
orjson series -> ['2020-01-01T00:00:00.000000', 'NaT']
orjson round -> ['2020-01-01T00:00:00.000000', 'NaT']
$ python -I repro.py | grep -E "series|round" # same filter at _json.py:517 too
json series -> ['2020-01-01T00:00:00.000000', None]
json round -> ['2020-01-01T00:00:00.000000', None]
orjson series -> ['2020-01-01T00:00:00.000000', None]
orjson round -> ['2020-01-01T00:00:00.000000', None]
# reverted: all four lines print 'NaT' again
No CODEOWNERS entry covers these paths. @camdecoster, would you take a PR with the filter at both sites and a datetime64 case next to test_pandas_json_encoding?
Activity
camdecoster commentedon Oct 20, 2026
Thanks for the report. Could you please explain how you encountered this in your daily usage?