[PR #6162] fix(langgraph): fix PostgresSaver crashing when loading older checkpoints #4879

Closed
opened 2026-02-20 17:50:53 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/langchain-ai/langgraph/pull/6162

State: closed
Merged: Yes


Description

https://github.com/langchain-ai/langgraph/issues/6137 and https://github.com/langchain-ai/langgraph/issues/5677 reported issues where older checkpoints read by AsyncPostgresSaver/PostgresSaver from langgraph-checkpoint-postgres==2.0.19 fail to read channel values, throwing NoneType object is not a mapping. This was due to a bug in how channel_values is assembled:

"channel_values": {
    **value["checkpoint"].get("channel_values"),  # <--- if channel_values doesn't exist (old checkpoint), **None errors
    **self._load_blobs(value["channel_values"]),
},

This bug was observed for checkpoints generated by langgraph-checkpoint-postgres<=2.0.19.

Fixed by providing a fallback to value["checkpoint"].get("channel_values"):

**value["checkpoint"],
"channel_values": {
    **(
        value["checkpoint"].get("channel_values") or {}
    ),  # 'or {}' needed for backwards compat with v3 checkpoints and below, as v4 introduced channel_values key
    **self._load_blobs(value["channel_values"]),
},

Tests

Added test for AsyncPostgresSaver and test for PostgresSaver, using monkeypatch to remove channel_values before CheckpointTuple is assembled in _load_checkpoint_tuple.

Solves

https://github.com/langchain-ai/langgraph/issues/6137 and https://github.com/langchain-ai/langgraph/issues/5677

**Original Pull Request:** https://github.com/langchain-ai/langgraph/pull/6162 **State:** closed **Merged:** Yes --- ### Description https://github.com/langchain-ai/langgraph/issues/6137 and https://github.com/langchain-ai/langgraph/issues/5677 reported issues where older checkpoints read by AsyncPostgresSaver/PostgresSaver from `langgraph-checkpoint-postgres==2.0.19` fail to read channel values, throwing `NoneType object is not a mapping`. This was due to a bug in how `channel_values` is assembled: ```python "channel_values": { **value["checkpoint"].get("channel_values"), # <--- if channel_values doesn't exist (old checkpoint), **None errors **self._load_blobs(value["channel_values"]), }, ``` This bug was observed for checkpoints generated by `langgraph-checkpoint-postgres<=2.0.19`. Fixed by providing a fallback to `value["checkpoint"].get("channel_values")`: ```python **value["checkpoint"], "channel_values": { **( value["checkpoint"].get("channel_values") or {} ), # 'or {}' needed for backwards compat with v3 checkpoints and below, as v4 introduced channel_values key **self._load_blobs(value["channel_values"]), }, ``` ### Tests Added test for AsyncPostgresSaver and test for PostgresSaver, using monkeypatch to remove `channel_values` before CheckpointTuple is assembled in `_load_checkpoint_tuple`. ### Solves https://github.com/langchain-ai/langgraph/issues/6137 and https://github.com/langchain-ai/langgraph/issues/5677
yindo added the pull-request label 2026-02-20 17:50:53 -05:00
yindo closed this issue 2026-02-20 17:50:53 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/langgraph#4879