{"record":{"id":"559a2270db71da2a","repo":"remix-run/react-router","slug":"method-call-aborted-without-an-abortsignal-r","errorCode":null,"errorMessage":"${method}() call aborted without an `AbortSignal.reason`: ${request.method} ${request.url}","messagePattern":"(.+?)\\(\\) call aborted without an `AbortSignal\\.reason`: (.+?) (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-router/lib/router/router.ts","lineNumber":5092,"sourceCode":"  return {\n    ...handlerContext,\n    statusCode: isRouteErrorResponse(error) ? error.status : 500,\n    errors: {\n      [errorBoundaryId]: error,\n    },\n  };\n}\n\nfunction throwStaticHandlerAbortedError(\n  request: Request,\n  isRouteRequest: boolean,\n) {\n  if (request.signal.reason !== undefined) {\n    throw request.signal.reason;\n  }\n\n  let method = isRouteRequest ? \"queryRoute\" : \"query\";\n  throw new Error(\n    `${method}() call aborted without an \\`AbortSignal.reason\\`: ${request.method} ${request.url}`,\n  );\n}\n\nfunction isSubmissionNavigation(\n  opts: BaseNavigateOrFetchOptions,\n): opts is SubmissionNavigateOptions {\n  return (\n    opts != null &&\n    ((\"formData\" in opts && opts.formData != null) ||\n      (\"body\" in opts && opts.body !== undefined))\n  );\n}\n\nfunction defaultNormalizePath(request: Request): Path {\n  let url = new URL(request.url);\n  return {\n    pathname: url.pathname,","sourceCodeStart":5074,"sourceCodeEnd":5110,"githubUrl":"https://github.com/remix-run/react-router/blob/1fd704a7dabcbe3ae09d7387b460e6acaba30ec1/packages/react-router/lib/router/router.ts#L5074-L5110","documentation":"`createStaticHandler.query()`/`queryRoute()` noticed `request.signal.aborted` but `signal.reason` is `undefined`, so there is no underlying error to rethrow. The handler throws a synthetic Error naming the method (`query`/`queryRoute`) and the aborted request so the caller can see *which* call was aborted.","triggerScenarios":"Caller aborts the `Request`'s `AbortSignal` without a reason (e.g. `controller.abort()` with no argument) while a static `query()`/`queryRoute()` is running, and the abort is observed by `throwStaticHandlerAbortedError`.","commonSituations":"Server-side rendering where the client disconnects and the framework aborts the request; calling `controller.abort()` directly without passing an Error; using an older runtime that doesn't populate `AbortSignal.reason`.","solutions":["Abort with a reason: `controller.abort(new Error('user navigated away'))` so the reason is propagated instead of the synthetic message.","If the abort is expected (client disconnect), catch and treat as a no-op rather than an error.","Upgrade Node/runtime to a version that always populates `signal.reason`."],"exampleFix":"// before\ncontroller.abort();\n\n// after\ncontroller.abort(new DOMException('User navigated away', 'AbortError'));","handlingStrategy":"try-catch","validationCode":"const controller = new AbortController();\ncontroller.abort(new DOMException('Reason', 'AbortError')); // always pass a reason\nconst request = new Request(url, { signal: controller.signal });","typeGuard":null,"tryCatchPattern":"try {\n  await staticHandler.query(request);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('aborted without an `AbortSignal.reason`')) {\n    // expected abort, ignore\n    return null;\n  }\n  throw e;\n}","preventionTips":["Always abort with a reason: `controller.abort(new Error('...'))`.","Treat client-disconnect aborts in SSR as benign.","Use a runtime that populates `AbortSignal.reason`."],"tags":["ssr","abort","static-handler","signals"],"backgroundTag":null,"analyzedSha":"1fd704a7dabcbe3ae09d7387b460e6acaba30ec1","analyzedAt":"2026-08-12T13:54:57.804Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}