Skip to content

qdrant-vectorize.ts's 5 Qdrant REST calls have no AbortSignal.timeout, unlike every other self-host external-fetch adapter #7072

Description

@JSONbored

Context

src/selfhost/qdrant-vectorize.ts implements a self-host Vectorize adapter backed by an operator's own Qdrant REST API (initQdrantCollection, and the upsert/query/deleteByIds methods of createQdrantVectorize). Every one of its 5 fetch() calls has no AbortSignal.timeout(...):

  • initQdrantCollection — line 72 (PUT .../collections/{collection}) and line 81 (GET .../collections/{collection})
  • upsert — line 102 (PUT .../points)
  • query — line 122 (POST .../points/search)
  • deleteByIds — line 149 (POST .../points/delete)

This is a self-host-only Node.js adapter (unlike the Cloudflare Workers runtime, which has its own platform-level subrequest ceiling), so an unresponsive or network-partitioned Qdrant instance can hang these calls indefinitely in the review/RAG pipeline's request-handling process. Every other external-HTTP self-host/review adapter in this audit's scope uses a bounded AbortSignal.timeout(...): src/selfhost/ai.ts (AbortSignal.timeout(120_000) on its embeddings/chat-completions/messages calls), src/review/visual/actions-fallback.ts (AbortSignal.timeout(DEFAULT_TIMEOUT_MS)), src/review/enrichment-wire.ts, src/review/alerts.ts, src/review/visual/capture.ts. qdrant-vectorize.ts is the one external-fetch adapter in src/selfhost/** with no timeout on any of its calls.

Note that query's fetch is already wrapped in a try/catch that degrades to { matches: [] } on any thrown error (so a rejected/aborted fetch there is already handled gracefully) — the gap is specifically the absence of any time bound, not missing error handling.

Requirements

  • Every fetch() call in src/selfhost/qdrant-vectorize.ts (initQdrantCollection's two calls, and upsert/query/deleteByIds) must pass an AbortSignal.timeout(...).
  • Introduce one named timeout constant at module scope (e.g. QDRANT_FETCH_TIMEOUT_MS), configurable via a sensible default (recommend 10-15 seconds, consistent with this file's other self-host-adapter siblings' order of magnitude) — a single shared constant for all 5 call sites is sufficient; this does not need to be separately configurable per operation.
  • upsert and deleteByIds currently throw a plain Error on any non-ok response; a timeout on either must continue to surface as a thrown error there (an AbortSignal.timeout rejection propagates out of the await fetch(...) call itself, so no new catch/throw logic is needed beyond adding the signal).
  • query's existing try { ... } catch { return { matches: [] } } around its fetch must continue to degrade to { matches: [] } on a timeout exactly as it already does for any other network failure (no behavior change needed there beyond adding the signal).
  • initQdrantCollection's two calls must continue to throw on failure exactly as today (a timeout naturally propagates as a rejected fetch, causing the existing throw paths to fire).

Deliverables

  • All 5 fetch() calls in src/selfhost/qdrant-vectorize.ts pass signal: AbortSignal.timeout(QDRANT_FETCH_TIMEOUT_MS) (or equivalent named constant).
  • A regression test for query asserting a hung fetch resolves to { matches: [] } within the bounded timeout.
  • A regression test for upsert (or deleteByIds) asserting a hung fetch rejects with a bounded-time error rather than hanging.
  • Existing success/non-ok-response tests continue to pass unchanged.

Test Coverage Requirements

src/selfhost/qdrant-vectorize.ts is under src/**, measured by Codecov. This PR must hit 99%+ patch coverage on every changed line and branch, including the timeout paths exercised by the regression tests above.

Expected Outcome

Every Qdrant REST call in src/selfhost/qdrant-vectorize.ts is bounded by an explicit timeout, consistent with every other external-HTTP self-host adapter in this codebase, so an unresponsive or network-partitioned Qdrant instance can no longer hang the self-host review/RAG request-handling process.

Links & Resources

  • src/selfhost/qdrant-vectorize.ts (initQdrantCollection, lines 66-89; createQdrantVectorize, lines 92-163)
  • Sibling timeout convention: src/selfhost/ai.ts (AbortSignal.timeout(120_000))

Metadata

Metadata

Assignees

No one assigned

    Labels

    gittensor:bugGittensor-scored bug fix — scores a 0.05x multiplier.help wantedExtra attention is needed

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions