langchain-ai / langchain-ai/langgraph

Topic/NamedBarrierValue from_checkpoint aliases the checkpoint container instead of copying

Open Beginner friendly
#7,992 8 comments 0 reactions 0 assignees View on GitHub
external
Dominant language
Python
Stars
41.8k
Forks
7.1k
Avg merge
23h 7m
Merged PRs (30d)
30

Description

### Description

`Topic.from_checkpoint` and `NamedBarrierValue.from_checkpoint` assign the checkpoint's container directly to the new channel instead of copying it:

```python
# topic.py
empty.values = checkpoint
# named_barrier_value.py
empty.seen = checkpoint
```

`BaseChannel.from_checkpoint` documents that "If the checkpoint contains complex data structures, they should be copied", and the channels' own `copy()` methods do copy (`self.values.copy()`, `self.seen.copy()`), but `from_checkpoint` does not. So two channels restored from the same checkpoint object share the same list/set, and an in-place update to one mutates the checkpoint and the sibling.

### Reproduction

```python
from langgraph.channels.topic import Topic

source = Topic(str, accumulate=True)
source.update(["a", "b"])
checkpoint = source.checkpoint()

one = Topic(str, accumulate=True).from_checkpoint(checkpoint)
two = Topic(str, accumulate=True).from_checkpoint(checkpoint)
one.update(["c"])

print(two.get()) # ['a', 'b', 'c'] -> expected ['a', 'b']
print(checkpoint) # ['a', 'b', 'c'] -> checkpoint was mutated
```

`NamedBarrierValue` (and `NamedBarrierValueAfterFinish`) behave the same way with their `seen` set. This matters when a single loaded checkpoint is reused across restores (replay / forking a thread): an `accumulate=True` topic or a barrier value can retroactively corrupt the persisted checkpoint.

### Expected

`from_checkpoint` should copy the container, like `copy()` already does, so restored channels are independent of the checkpoint and of each other.

### System info

langgraph main; the affected code is in `langgraph/channels/topic.py` and `langgraph/channels/named_barrier_value.py`.

Contributor guide

Open the contributing guide

Research direction

Start with langgraph/channels/topic.py and langgraph/channels/named_barrier_value.py, then review BaseChannel.from_checkpoint and the channels' copy() methods. Reproduce the issue with the Topic example and add or run focused tests for Topic and NamedBarrierValue, including NamedBarrierValueAfterFinish. Done means restored channels are independent from the checkpoint and from one another.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.