{"record":{"id":"5eb32407c991f34c","repo":"JuliusBrussee/caveman","slug":"this-operation-was-aborted","errorCode":null,"errorMessage":"This operation was aborted","messagePattern":"This operation was aborted","errorType":"exception","errorClass":"DOMException","httpStatus":null,"severity":"warning","filePath":"packages/cli/src/proxy-fetch.ts","lineNumber":241,"sourceCode":"      // Plain HTTP is proxied in absolute form; no tunnel needed.\n      void finish(\n        {\n          host: proxy.hostname,\n          port: portOf(proxy),\n          method,\n          path: url.toString(),\n          headers: { ...headers, host: url.host, ...proxyAuthHeader(proxy) },\n        },\n        sendToProxy,\n      );\n      return;\n    }\n\n    openTunnel(url, proxy, signal)\n      .then((socket) => {\n        if (signal?.aborted) {\n          socket.destroy();\n          throw abortError();\n        }\n        return finish(\n          {\n            method,\n            path: `${url.pathname}${url.search}`,\n            headers: { ...headers, host: url.host },\n            // Node 26 rejects an IP literal as SNI servername; omit it for IP targets.\n            createConnection: () => tlsConnect({ socket, host: url.hostname, servername: isIP(url.hostname) ? undefined : url.hostname }),\n          },\n          httpsRequest,\n        );\n      })\n      .catch(reject);\n  });\n}\n\nasync function bufferedRequestBody(request: Request): Promise<Uint8Array | null> {\n  if ([\"GET\", \"HEAD\"].includes(request.method)) return null;","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/cli/src/proxy-fetch.ts#L223-L259","documentation":"The fetch operation was aborted through its AbortSignal while a proxied HTTPS request was being set up: after the CONNECT tunnel opened, the signal was already aborted, so the tunnel socket is destroyed and a standard DOM-style AbortError (\"This operation was aborted\") is thrown instead of issuing the request. This mirrors the fetch spec behavior of rejecting with an abort error when a signal fires.","triggerScenarios":"Calling the proxy-aware fetch (via `caveman` CLI network paths) with `init.signal` and aborting the controller while the HTTPS CONNECT tunnel to the proxy is opening, or passing an already-aborted signal that races the tunnel `.then` handler; the abort listener attached to the outbound request also destroys the socket with this error.","commonSituations":"CLI commands with their own request timeouts aborting in-flight proxied calls, users pressing Ctrl-C, or an upstream caller cancelling a request whose proxy tunnel handshake is slow (common with slow/blocked corporate proxies).","solutions":["Expected behavior: handle the AbortError in your calling code (check `error.name === \"AbortError\"`) rather than treating it as a network failure.","Increase or remove the timeout that fires the AbortController for slow proxied requests.","Check proxy reachability/latency (HTTP_PROXY/HTTPS_PROXY env) — slow tunnels make aborts more likely.","Abort only after the response has been consumed if you need the body."],"exampleFix":"// before\nconst res = await fetch(url, { signal: controller.signal });\n// after\ntry {\n  const res = await fetch(url, { signal: controller.signal });\n} catch (e) {\n  if (e.name === \"AbortError\") return null; // expected cancellation\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"if (signal?.aborted) return; // skip the call entirely before fetching","typeGuard":"function isAbortError(e: unknown): e is DOMException {\n  return e instanceof Error && e.name === \"AbortError\";\n}","tryCatchPattern":"try {\n  const res = await proxyAwareFetch(url, { signal: controller.signal });\n} catch (e) {\n  if (isAbortError(e)) return null; // expected cancellation, not a network failure\n  throw e;\n}","preventionTips":["Set request timeouts generously for proxied HTTPS (CONNECT adds a handshake hop).","Check signal.aborted before issuing each fetch.","Verify HTTP_PROXY/HTTPS_PROXY reachability; slow proxies inflate tunnel time.","Don't abort while a response body is still being consumed."],"tags":["abort","fetch","proxy","network"],"backgroundTag":"request-timeout","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}