Problem
In LocalCollection.update_vectors(), when processing a batch of points with an update_filter, if any point doesn't match the filter, the function executes return None (line 2649), which exits the entire function immediately. This causes all remaining points in the batch to be silently skipped.
Root Cause
# local_collection.py, line 2646-2649
if not check_filter(
update_filter, self.payload[idx], self.ids_inv[idx], has_vector
):
return None # BUG: should be "continue"
return None exits the entire update_vectors method. It should be continue to skip only the current point and process the remaining ones.
Impact
When calling update_vectors with multiple points and an update_filter:
- If point N doesn't match the filter, points N+1, N+2, ... are never updated
- The caller gets
None instead of UpdateResult, with no indication that points were skipped
- This is a silent data loss bug — updates that should succeed are discarded
Steps to Reproduce
from qdrant_client import QdrantClient
from qdrant_client.models import VectorParams, Distance, PointStruct, PointVectors, Filter, FieldCondition, MatchValue
client = QdrantClient(path="/tmp/test_db")
client.create_collection("test", vectors_config=VectorParams(size=4, distance=Distance.COSINE))
# Insert 3 points
client.upsert("test", points=[
PointStruct(id=1, vector=[1,0,0,0], payload={"type": "a"}),
PointStruct(id=2, vector=[0,1,0,0], payload={"type": "b"}),
PointStruct(id=3, vector=[0,0,1,0], payload={"type": "a"}),
])
# Update vectors with filter matching only type="a"
# Point 2 (type="b") doesn't match, so points 3 is also skipped
client.update_vectors("test", points=[
PointVectors(id=1, vector=[0.5, 0.5, 0, 0]),
PointVectors(id=2, vector=[0, 0, 0.5, 0.5]), # doesn't match filter
PointVectors(id=3, vector=[0, 0, 0, 1]), # matches filter but gets skipped!
], update_filter=Filter(must=[FieldCondition(key="type", match=MatchValue(value="a"))]))
# Point 3 should have been updated but wasn't
Proposed Fix
Change return None to continue on line 2649:
if not check_filter(
update_filter, self.payload[idx], self.ids_inv[idx], has_vector
):
continue # Skip this point, process the rest
Verification
After the fix, all points matching the filter should be updated regardless of their position in the batch.
Problem
In
LocalCollection.update_vectors(), when processing a batch of points with anupdate_filter, if any point doesn't match the filter, the function executesreturn None(line 2649), which exits the entire function immediately. This causes all remaining points in the batch to be silently skipped.Root Cause
return Noneexits the entireupdate_vectorsmethod. It should becontinueto skip only the current point and process the remaining ones.Impact
When calling
update_vectorswith multiple points and anupdate_filter:Noneinstead ofUpdateResult, with no indication that points were skippedSteps to Reproduce
Proposed Fix
Change
return Nonetocontinueon line 2649:Verification
After the fix, all points matching the filter should be updated regardless of their position in the batch.