Skip to content

Classify Qdrant errors by status code alone - #1779

Merged
edwinyyyu merged 1 commit into
MemMachine:feat/horizontal-scalingfrom
edwinyyyu:fix/qdrant-remote-error-classification-speedkick
Oct 7, 2026
Merged

edwinyyyu merged 1 commit into
MemMachine:feat/horizontal-scalingfrom
edwinyyyu:fix/qdrant-remote-error-classification-speedkick

Conversation

@edwinyyyu

@edwinyyyu edwinyyyu commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Purpose of the change

Summary

The Qdrant store's already-exists and not-found checks also matched a ValueError by its message text, and its collection preparation, payload index creation, and purge caught ValueError for them. Only qdrant-client's local mode raises those errors, and the store runs only against a server: over REST the client raises UnexpectedResponse with an HTTP status, and over gRPC AioRpcError with a status code. The message match and the ValueError catches go; both checks classify by status code alone.

Commits

  1. Classify Qdrant errors by status code alone.

Stack

22 open PRs: three independent PRs, and the vector store tree of short parallel branches. #1736's, #1779's, and #1788's GitHub base is feat/horizontal-scaling and the others' is main, since the branches are in a fork and a pull request can target only this repository's branches; the on column gives the order the PRs build on each other instead. A stacked PR's diff on GitHub includes the PRs under it until they merge.

Independent of the vector store tree, directly on main:

# PR change on
— #1624 Make no memory request create a project main
— #1786 Refuse a filter value of the wrong type for a datetime column, and answer an invalid list filter with 422 (port of #1620) main
— #1792 Refuse property values that some store refuses or alters where an episode enters main

The vector store tree. Each PR builds on the one in its on column; PRs on the same parent are parallel branches and do not depend on each other. #1631 is closed, superseded by #1733–#1736, which hold its changes split in four, with review changes since. #1670 and #1702 sit beneath #1627, whose code depends on them. Until the PRs under it merge, their changes show in a stacked PR's diff.

# PR change on
[vector store scale-out 1/6] #1671 (merged) Remove custom sharding from the Qdrant store (port of #1654) main
[vector store scale-out 2/6] #1733 (merged into feat/horizontal-scaling) Answer vector store queries with record UUIDs and scores, and refuse invalid inputs feat/horizontal-scaling
[vector store scale-out 3/6] #1734 (merged into feat/horizontal-scaling) Arbitrate vector store collections in a SQL registry, with an incarnation per collection life and a purge feat/horizontal-scaling
[vector store scale-out 4/6] #1735 (merged into feat/horizontal-scaling) Move the Qdrant store onto the collection registry feat/horizontal-scaling
[vector store scale-out 5/6] #1736 Move the Milvus store onto the collection registry, against a Milvus server feat/horizontal-scaling
— #1775 (merged into feat/horizontal-scaling) Accept attempts exhausted in the lifecycle churn contract, and say which Qdrant operations filter on the incarnation feat/horizontal-scaling
— #1779 (this PR) Classify Qdrant errors by status code alone feat/horizontal-scaling
— #1788 Refuse a repeated record UUID or a non-finite property value at upsert, and state the datetime property contract #1736
— #1631 (closed) Superseded by #1733–#1736, which hold its changes split in four, with review changes since —
[user properties 1/2] #1670 Remove per-project filterable properties (port of #1606) #1736
[user properties 2/2] #1702 Keep user properties out of the vector store #1670
[vector store scale-out 6/6] #1627 Make a vector store one collection, with string-keyed partitions #1702
[session storage 1/2] #1622 Create a session's storage with the session, never on a request #1627
[session storage 2/2] #1625 Remove open-or-create from both stores, and close from the segment store #1622
[search results] #1663 Score every vector search by cosine similarity, and name scores for it (port of #1598's cosine half) #1627
[sqlite store fixes 1/7] #1460 Publish vector index files atomically (but not durably) #1663
[sqlite store fixes 2/7] #1469 Never reuse a row id in SQLiteVectorStore #1460
[sqlite store fixes 3/7] #1672 Own the search engine's concurrency in the store, not in each engine (port of #1612) #1469
[sqlite store fixes 4/7] #1673 Serialize a partition's writes so the engine sees them in order (port of #1607) #1672
[sqlite store fixes 5/7] #1674 Refuse a pending row replay cannot honor, instead of dropping it (port of #1608) #1673
[sqlite store fixes 6/7] #1675 Take SQLite's write lock at BEGIN, not at the first write (port of #1609) #1674
[sqlite store fixes 7/7] #1676 Give every write a fresh row id, so a key names one version (port of #1610) #1675
[qdrant options] #1618 Let a deployment tune a Qdrant collection's HNSW, optimizers and quantization #1663
[declared schema 1/2] #1628 Make a vector store filter only on the properties it declares #1663
[declared schema 2/2] #1616 Close the filter union, and make negation the complement on every backend #1628

This PR is its one commit, 8f69592db, directly on feat/horizontal-scaling.

Verification

At the head: ruff check, ruff format --check, and ty check are clean; the full server suite without integration tests passes (2181 passed, 8 skipped); in test containers, the Qdrant store's and the resource manager's integration tests pass against Qdrant 1.19.1 and PostgreSQL (211 passed), over REST and gRPC, the racing creation tests among them. In qdrant-client 1.19.0, outside local mode, only the unused migration helper raises a ValueError naming an existing or missing resource.

🤖 Generated with Claude Code

The already-exists and not-found checks also matched a ValueError by its
message text. Only qdrant-client's local mode raises those, and the store
no longer runs in local mode: against a server, the client raises
UnexpectedResponse with an HTTP status over REST and AioRpcError with a
gRPC status code over gRPC. The message match and the ValueError the
preparation and purge caught for it go.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@edwinyyyu edwinyyyu added horizontal scaling Wrong or unsafe when more than one server process serves the same backends (replicas or workers) and removed horizontal scaling Wrong or unsafe when more than one server process serves the same backends (replicas or workers) labels Oct 7, 2026
This was referenced Oct 7, 2026
@edwinyyyu
edwinyyyu merged commit dc53da8 into MemMachine:feat/horizontal-scaling Oct 7, 2026
39 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant