{"record":{"id":"475b734318277790","repo":"upstash/context7","slug":"timedout-request-timeout-request-aborted","errorCode":"timedOut ? \"request_timeout\" : \"request_aborted\"","errorMessage":"timedOut ? \"Request timed out\" : \"Request was aborted\"","messagePattern":"timedOut \\? \"Request timed out\" : \"Request was aborted\"","errorType":"error_code","errorClass":"Context7Error","httpStatus":null,"severity":"warning","filePath":"packages/sdk/src/http/index.ts","lineNumber":85,"sourceCode":"\n  public async request<TResult>(request: Context7Request): Promise<Context7Response<TResult>> {\n    const method = request.method ?? \"POST\";\n    const abortState = createAbortState(\n      [resolveSignal(this.options.signal), request.signal],\n      request.timeout ?? this.options.timeout\n    );\n    const init: RequestInit = {\n      cache: normalizeCache(request.cache ?? this.options.cache),\n      method,\n      headers: this.headers,\n      body: request.body === undefined ? undefined : JSON.stringify(request.body),\n      keepalive: this.options.keepAlive,\n      signal: abortState.signal,\n    };\n\n    try {\n      if (abortState.signal?.aborted) {\n        throw abortError(abortState.signal.reason, abortState.timedOut());\n      }\n\n      const { response, metadata } = await this.fetchWithRetry(\n        buildUrl(this.baseUrl, method, request),\n        init,\n        method,\n        abortState\n      );\n      if (!response.ok) {\n        await throwResponseError(\n          response,\n          metadata,\n          isTransientStatus(response.status) || this.retry.statuses.has(response.status)\n        );\n      }\n      return await parseSuccessResponse<TResult>(response, metadata);\n    } catch (error) {\n      if (abortState.signal?.aborted && !isContext7AbortError(error)) {","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/upstash/context7/blob/80e681a507c5287bc12e483367c40754e29461b9/packages/sdk/src/http/index.ts#L67-L103","documentation":"Context7Error (code \"request_timeout\" or \"request_aborted\") thrown by request when the abort signal is already aborted before/at the start of the fetch — i.e. the request timed out per the configured timeout, or the caller aborted via an external AbortSignal, before the request could run.","triggerScenarios":"Passing a signal option that is already aborted, using an AbortSignal.timeout(ms) that fired before the call, or a client-level timeout that elapsed between requests so abortState.signal.reason triggers abortError at request entry.","commonSituations":"Reusing a timed-out AbortSignal.timeout token, a shared cancellation controller aborted by another request, or very small timeout values in slow environments.","solutions":["Create a fresh AbortSignal per request (AbortSignal.timeout(ms) or new AbortController().signal) instead of reusing an already-aborted one.","Increase the client timeout option (timeout in ms) or set timeout: false if the operation legitimately takes longer.","Check upstream caller code that aborts the shared controller and only abort after the request completes.","Catch the error and check code === 'request_timeout' vs 'request_aborted' to distinguish timeout from deliberate cancellation."],"exampleFix":"// before\nconst signal = AbortSignal.timeout(1000);\nawait slowWork(); // >1s\nawait client.exec(cmd, { signal }); // aborted before start\n// after\nconst signal = AbortSignal.timeout(10000); // fresh, adequately sized\nawait client.exec(cmd, { signal });","handlingStrategy":"try-catch","validationCode":"const signal = mySignal;\nif (signal?.aborted) throw new Error('Refusing to call: signal already aborted');","typeGuard":"function isAbortFailure(e: unknown): e is Context7Error {\n  return e instanceof Context7Error && (e.code === 'request_timeout' || e.code === 'request_aborted');\n}","tryCatchPattern":"try {\n  return await client.exec(cmd, { signal });\n} catch (e) {\n  if (isAbortFailure(e)) {\n    if (e.code === 'request_aborted') return undefined; // deliberate cancel\n    return await client.exec(cmd); // timeout: retry with fresh default timeout\n  }\n  throw e;\n}","preventionTips":["Create a fresh AbortSignal/AbortController per request.","Never reuse AbortSignal.timeout tokens after awaits.","Size timeouts to the slowest realistic upstream response.","Don't share one AbortController across unrelated concurrent requests."],"tags":["timeout","abort","http"],"backgroundTag":"request-timeout","analyzedSha":"80e681a507c5287bc12e483367c40754e29461b9","analyzedAt":"2026-09-08T05:18:41.043Z","contentChangedAt":"2026-09-08T05:18:41.043Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}