A checkpoint can restore a Python datetime that still compares equal to the original and yet behave differently the next time your workflow crosses a DST boundary. I reproduced that failure shape against LangGraph upstream commit 81bf17b23 with langgraph-checkpoint 4.2.0 metadata.
The surprising part is not a crash. The serializer succeeds. The instant survives. What disappears is the IANA timezone rule and the fold bit.
Minimal reproduction
Python 3.10, JsonPlusSerializer, no model calls, no database, no LangSmith:
before_tz= zoneinfo.ZoneInfo(key='America/New_York')
after_tz= datetime.timezone(... -05:00)
equal= True
before_plus1= 2026-03-08 09:00:00-04:00
after_plus1= 2026-03-08 10:00:00-04:00
fold= 1 -> 0
Result: REPRODUCED
equal=True is exactly why a normal round-trip test can miss the bug. A fixed UTC-05:00 offset can represent the same instant as ZoneInfo("America/New_York"), but it does not know that New York switches to UTC-04:00 the next day.
Why +1 day becomes one hour wrong
The fixture starts at 2026-03-07 09:00 in New York and adds one day across the spring DST transition. Before serialization the wall clock remains 09:00. After restore the fixed-offset datetime produces 10:00.
This matters for reminders, appointments, market schedules, billing cutoffs and long-running agent routines. An absolute event stored in UTC is much less exposed.
fold is a separate piece of state
Python's fold distinguishes the two copies of an ambiguous local time when clocks move backward. In the same round trip, fold=1 became fold=0. A robust regression therefore checks more than equality:
assert getattr(restored.tzinfo, "key", None) == "America/New_York"
assert restored.fold == before.fold
assert restored + timedelta(days=1) == expected_local_time_next_day
A containment pattern that passed locally
Until a released upstream fix is regression-tested in your stack, persist timezone semantics explicitly:
payload = {
"instant": value,
"zone": "America/New_York",
"fold": value.fold,
}
Then rebuild with ZoneInfo after restore. The fixture returned:
restored_tz=zoneinfo.ZoneInfo(key='America/New_York')
next_day=2026-03-08 09:00:00-04:00
CONTAINMENT_OK
This is application-level containment, not an upstream LangGraph fix. It cannot reconstruct an IANA zone from an old fixed offset if the original zone was never stored.
Practical rule
Use UTC for absolute events. For schedules with local-time meaning, persist the IANA timezone key explicitly, preserve fold when ambiguous times matter, and include DST-crossing arithmetic in checkpoint regression tests.
Repro: github.com/xbstack/langgraph-zoneinfo-fold-checkpoint-repro.
Original XBSTACK article: https://www.xbstack.com/en/ai/langgraph-checkpoint-zoneinfo-fold-dst/?utm_source=devto&utm_medium=referral&utm_campaign=langgraph_zoneinfo_fold_checkpoint&utm_content=original
Related:



Top comments (0)