langchain-ai / langchain-ai/langgraph
Add restart-safety coverage for put_writes idempotency
- Dominant language
- Python
- Stars
- 41.9k
- Forks
- 7.1k
- Avg merge
- 23h 7m
- Merged PRs (30d)
- 30
Description
Problem
The shared conformance suite verifies duplicate `put_writes` calls within one saver instance, but it does not currently protect the retry-safe contract across saver restarts, which is the operational case users hit after process or network failure.
Why now
`put_writes` is the pending-write boundary for resumed graphs. A restart-specific regression would not be caught by the existing `test_put_writes_idempotent` coverage even though the runtime contract is supposed to survive retries.
Evidence packet
- Commit under test: `0f2478cecbd55de8beeb22f87dce5dbafd9ace78`
- Runtime: macOS 15.3 / Darwin 25.3.0 arm64, Python `3.14.0`
- Relevant codepaths:
- `libs/checkpoint-conformance/langgraph/checkpoint/conformance/spec/test_put_writes.py`
- `libs/checkpoint-postgres/langgraph/checkpoint/postgres/base.py`
- `libs/checkpoint-sqlite/langgraph/checkpoint/sqlite/__init__.py`
- Minimal repro:
1. Persist a checkpoint.
2. Call `put_writes` / `aput_writes` for a task.
3. Re-open the saver and replay the exact same payload.
4. Read `pending_writes` back from `get_tuple` / `list`.
- Expected: one stable pending-write set after replay, unchanged by the second write.
- Actual: current conformance coverage exercises only same-process duplicates, so restart regressions can slip through unnoticed.
Scope
This is a contract-validation gap around runtime behavior, not a broad framework redesign.
Validation target
Add restart-aware coverage that fails if replaying the same pending writes after re-opening the saver duplicates or mutates checkpoint state.
Contributor guide
Research direction
Start with libs/checkpoint-conformance/langgraph/checkpoint/conformance/spec/test_put_writes.py and the existing test_put_writes_idempotent coverage. Reopen the saver after writing, replay the same payload, and inspect pending_writes through get_tuple or list for the PostgreSQL and SQLite implementations. Done means the replay leaves one stable pending-write set without duplicating or mutating checkpoint state.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend, testing
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100