Repository navigation
fix(langchain): align Store deletion, validation and removal errors - #6324
Merged
Merged
Conversation
(cherry picked from commit 9cc5841) Signed-off-by: Hao Zhe <[email protected]>
LangGraph's BaseStore contract treats a None value passed to put() as a deletion. OpenVikingStore.batch() already dispatched PutOp with a None value to delete(), and the inherited aput() reaches the same path through abatch(), but the sync put() override wrote None straight through the ordinary JSON record path. Before this change, put(namespace, key, None) stored a record whose value was null: get() returned an Item with value None, search() still listed the record, and list_namespaces() kept exposing the namespace. Calling it on a key that did not exist created a new null-valued record instead of doing nothing. The sync put() now delegates the None case to the existing delete(), after the unsupported-TTL guard so that put(..., None, ttl=...) still raises NotImplementedError and stays consistent with aput(). get() now returns None, search() omits the item, the namespace disappears once its last record is removed, and deleting a missing key is a no-op. The value annotation was widened to dict[str, Any] | None to match BaseStore. (cherry picked from commit 8578bd0) Signed-off-by: Hao Zhe <[email protected]>
…olcengine#5821) LangGraph's BaseStore.put() defines value=None as a deletion signal. The OpenViking adapter's batch / async paths already routed None through self.delete(...), but the sync put() override wrote the None through the ordinary JSON storage path, persisting a record whose value is JSON null. After the fix, put(namespace, key, None) delegates to delete(namespace, key) and returns, matching the public BaseStore contract: - get() returns None for the deleted key. - search() no longer returns the deleted item. - list_namespaces() no longer keeps the deleted item's namespace. - Deleting a missing key is a no-op (no null-valued record is created). The value type annotation is widened to "Mapping[str, Any] | None" to match the call sites batch already uses (op.value is forwarded as-is). (cherry picked from commit 564f8f1) Signed-off-by: Hao Zhe <[email protected]>
(cherry picked from commit d9a8c82) Signed-off-by: Hao Zhe <[email protected]>
(cherry picked from commit 13a9e2c) Signed-off-by: Hao Zhe <[email protected]>
Keep contributed deletion coverage in the adapter suite and remove overlapping assertions. Exercise sync, async and batch removal failures, partial cleanup and retry, invalid put(None) namespaces, independent items and unsupported TTL. Document partial removal behavior. Signed-off-by: Hao Zhe <[email protected]>
t0saki
approved these changes
Oct 20, 2026
This was referenced Oct 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Align
OpenVikingStoremutations with their public LangGraph contracts:put(namespace, key, None)raisesTypeErrorand leaves the item in place. It now delegates to the existing deletion path, including removal of the search projection. Missing keys remain a no-op.("users", "", "ada")can overwrite("users", "ada"). Syncput()now reuses LangGraph's namespace validator before writing or dispatching deletion, matching the inherited async validation.index=Falseupdates, including async and batch entrypoints.Record and projection removal remain separate operations. A partial failure is reported, and callers can retry after resolving it. Existing URI encoding, Mapping support and unsupported-TTL behavior are preserved.
Human Involvement
Related Issue
Fixes #5821
Fixes #5774
Fixes #6050
Consolidates the overlapping deletion fixes in #5823, #5886 and #6022, plus the related mutation fixes in #5777 and #6051.
Type of Change
Changes Made
delete(),is_not_found_error()and LangGraph's validator.put(None)calls, existing/missing keys, index overrides, ordinary values, TTL rejection, independent items, partial cleanup, explicit retry and batch interruption.Testing
59ef89730, and all 90 pass here. The bugs were also reproduced independently through public Store calls before applying the commits.Skips are the optional SQLite checkpointer and, on Python 3.10,
asyncio.timeout. Existing dependency deprecation warnings remain. The HTTP fixture uses deterministic storage and controlled errors; it does not validate a deployed backend, authorization policy, vector service or external model.Checklist
Screenshots (if applicable)
Not applicable.
Additional Notes
Original commits were cherry-picked with
-x, preserving their authorship:9cc584117), fix(langchain): propagate store removal failures #5777 (d9a8c8236), fix(langchain): validate namespaces before sync Store writes #6051 (13a9e2c0c).8578bd021).564f8f158).Overlapping deletion code and tests are consolidated. Test relocation, additional contract coverage and documentation updates are a separate signed-off commit by Hao Zhe. The source PRs remain open until this combined fix lands.