abhigyanpatwari/GitNexus · info · HttpEmbeddingError

Embedding request cancelled

Error message

Embedding request cancelled (${safeUrl(url)}, batch ${batchIndex})

What it means

httpEmbedBatch's catch maps AbortError (the caller's AbortSignal aborted, or a DOMException named AbortError) to HttpEmbeddingError 'Embedding request cancelled'. Cancellation is honored across the whole retry loop — abortableSleep and the fetch signal stop retries immediately; this is a cooperative cancel, not a failure.

Solutions

  1. Treat as expected control flow — catch HttpEmbeddingError and inspect cause/name for AbortError instead of retrying.
  2. If it fires spuriously, raise the outer deadline/timeout that owns the signal.
  3. Don't reuse an already-aborted signal across embedding calls.
  4. For real per-request timeouts prefer GITNEXUS_EMBEDDING_HTTP_TIMEOUT_MS so the error is classified as a timeout, not a cancel.

Example fix

// before
const ctrl = new AbortController();
setTimeout(() => ctrl.abort(), 100); // too tight
await httpEmbedQuery(q, { signal: ctrl.signal });
// after
const ctrl = new AbortController();
setTimeout(() => ctrl.abort(), 60_000);
try {
  await httpEmbedQuery(q, { signal: ctrl.signal });
} catch (e) {
  if (e instanceof HttpEmbeddingError && e.cause?.name === 'AbortError') return []; // graceful cancel
  throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

const aborted = (signal?: AbortSignal): boolean => !!signal?.aborted;
if (aborted(mySignal)) return; // don't even start

Type guard

const isEmbeddingCancel = (e: unknown): boolean =>
  e instanceof Error && e.message.includes('Embedding request cancelled');

Try / catch

try {
  vectors = await httpEmbed(texts, { signal });
} catch (e) {
  if (isEmbeddingCancel(e) || (e as DOMException)?.name === 'AbortError') {
    return; // cooperative cancel — not an error path
  }
  throw e;
}

Prevention

When it happens

Trigger: The caller passes an AbortSignal and aborts it mid-flight: MCP request cancellation, CLI Ctrl+C racing a slow endpoint, or an outer AbortSignal.timeout(...) firing as a timeout while a batch is in progress.

Common situations: Editor LSP/MCP clients cancelling in-flight semantic queries, servers with aggressive request deadlines, or tests that abort to clean up.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-08-20). Data as JSON: /api/errors/a7bcea11425cdb53. Report an issue: GitHub.

Appendix: source

Thrown at gitnexus/src/core/embeddings/http-client.ts:544

          parsed = payload.data;
          return attemptResp;
        },
        breakerKey: HTTP_BREAKER_KEY,
        retry: {
          maxAttempts,
          baseDelayMs: HTTP_RETRY_BACKOFF_MS,
          capDelayMs: retryCapMs,
          retryAfterCapMs: retryCapMs,
          sleep: (ms) => abortableSleep(ms, requestOptions.signal),
        },
      },
    );
  } catch (err) {
    if (
      requestOptions.signal?.aborted ||
      (err instanceof DOMException && err.name === 'AbortError')
    ) {
      throw new HttpEmbeddingError(
        `Embedding request cancelled (${safeUrl(url)}, batch ${batchIndex})`,
        { cause: err },
      );
    }
    // Retries are exhausted on a bad 2xx body. Surface the message the sentinel
    // carried, keeping the underlying parse error in `cause` only — the body
    // text must never reach the `sanitizeReason` fallback and leak to stderr.
    if (err instanceof RetryableEmbeddingBodyError) {
      throw new HttpEmbeddingError(err.terminalMessage, { cause: err.cause });
    }
    if (err instanceof RetryableEmbeddingTimeoutError) {
      throw new HttpEmbeddingError(
        `${err.message} after ${maxAttempts} attempt(s) (${safeUrl(url)}, batch ${batchIndex})`,
        { cause: err.cause },
      );
    }
    if (err instanceof CircuitOpenError) {
      throw new HttpEmbeddingError(

View on GitHub (pinned to ac9a4e9abd)