What happened
A VectorStoreCollection handle stays usable after its collection is deleted, and its writes reach the collection that replaces it.
QdrantVectorStore uses the logical name directly as the tenant discriminator, with nothing distinguishing one incarnation of a name from the next:
partition_key=name,
shard_key=name if self._is_distributed else None,
So: open a collection, hold the handle, delete the collection, create one with the same (namespace, name), then write through the old handle. The record carries the same partition key the new collection reads, and is returned by its queries.
This needs no concurrency to reproduce — a purely sequential create / open / delete / create / write sequence is enough.
Expected
A handle is invalid once its collection is deleted, and a write through one must never become visible in a collection later created with the same namespace and name.
Fix
Give each creation a fresh incarnation and make the partition key carry it, so records written through a stale handle land under a value nothing resolves to. #1527 does this.
Notes
Same defect class as #1536, which covers both SQLite-backed vector stores. This is the Qdrant instance of it. #1531 states the invariant as a VectorStoreCollection contract.
What happened
A
VectorStoreCollectionhandle stays usable after its collection is deleted, and its writes reach the collection that replaces it.QdrantVectorStoreuses the logical name directly as the tenant discriminator, with nothing distinguishing one incarnation of a name from the next:So: open a collection, hold the handle, delete the collection, create one with the same
(namespace, name), then write through the old handle. The record carries the same partition key the new collection reads, and is returned by its queries.This needs no concurrency to reproduce — a purely sequential create / open / delete / create / write sequence is enough.
Expected
A handle is invalid once its collection is deleted, and a write through one must never become visible in a collection later created with the same namespace and name.
Fix
Give each creation a fresh incarnation and make the partition key carry it, so records written through a stale handle land under a value nothing resolves to. #1527 does this.
Notes
Same defect class as #1536, which covers both SQLite-backed vector stores. This is the Qdrant instance of it. #1531 states the invariant as a
VectorStoreCollectioncontract.