Conversation
The server merges a set_payload request into the target object with merge_map, which removes a key whose new value is null instead of storing the null. Local mode used dict.update() and stored the nulls, so the same request left different payloads on the server and in local mode. This holds with and without `key`, and for the paths that replace a non-object target. Nulls nested inside a value are still stored as is, as on the server. overwrite_payload and upsert keep nulls on both sides and are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
✅ Deploy Preview for poetic-froyo-8baba7 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (4)
Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review. 📝 WalkthroughWalkthroughPayload updates now remove destination keys when the matching source value is null. This behavior applies to unkeyed local collection updates and terminal key, index, and wildcard paths. Non-dictionary values at terminal paths are replaced with dictionaries that omit null-valued source keys. Tests cover local path cases and compare local and remote collection results. Priority: ➖ Normal Estimated code review effort: 2 (Simple) | ~12 minutes Change: Bug fix Merge Risk: ⚪ Minimal · up to The null-removal change has no identified issue that needs resolution before merge. Proceed with normal checks. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The change intentionally replaces stored nulls with key deletion, so callers relying on the previous local behavior will observe different payloads. The inspected implementation preserves existing point selection and write scope; no new security boundary or privilege expansion was identified. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
When
set_payloadreceives a top-levelnullvalue, the server removes that key from the target object; local mode stores thenullinstead.On the server, every
set_payloadends inmerge_map, which removes a key whose value isValue::Nullinstead of inserting it. That covers the no-key case (Payload::merge) and every path handled byJsonPath::value_set, including paths whose target is not an object and gets replaced by a new one. Local mode merged withdict.update()/{**a, **b}and kept the nulls. The same applies toSetPayloadOperationinbatch_update_points.This adds a
merge_payloadhelper with the server's semantics and uses it everywhere local mode merges aset_payloadvalue: the no-key path and the terminal writes of the key, index and wildcard setters. Nulls nested inside a value ({"e": {"f": None}}) are still stored, as on the server.overwrite_payloadandupsertkeep nulls on both sides and are not changed.Tests
test_set_value_by_key_null_removes_key: one case per setter branch (dict target, non-dict target replaced, missing path, index, wildcard). All 7 fail before this change.test_set_payload_null_removes_key(congruence): the same request with no key and withb,a.x,arr[0],arr[1],arr[]andnew.path, over REST and gRPC. It fails before this change and passes after.Local runs against Qdrant v1.19.1 (
merge_mapandvalue_setare identical ondev):I found this with a small script that runs random
set_payload/overwrite_payload/delete_payload/clear_payloadcalls against both a server and:memory:and compares the payloads afterwards. Before the change, 7 of 300 rounds diverged, all because of nulls; after the change, 0 of 900 diverged.ruff format(v0.4.3, line length 99) andmypyreport no issues for the changed files.All Submissions:
devbranch. Did you create your branch fromdev?Changes to Core Features:
AI-assisted: the comparison script, fix and tests were prepared and run with Claude Code.
🤖 Generated with Claude Code