{"record":{"id":"298324e4343e21d0","repo":"remix-run/react-router","slug":"getrequest-must-be-called-from-within-a-react-serv","errorCode":null,"errorMessage":"getRequest must be called from within a React Server render context","messagePattern":"getRequest must be called from within a React Server render context","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/react-router/lib/rsc/server.rsc.ts","lineNumber":98,"sourceCode":"\ntype ServerContext = {\n  redirect?: Response;\n  request: Request;\n  runningAction: boolean;\n};\n\nconst globalVar = (typeof globalThis !== \"undefined\" ? globalThis : global) as {\n  ___reactRouterServerStorage___?: AsyncLocalStorage<ServerContext>;\n};\n\nconst ServerStorage = (globalVar.___reactRouterServerStorage___ ??=\n  new AsyncLocalStorage<ServerContext>());\n\nexport function getRequest() {\n  const ctx = ServerStorage.getStore();\n\n  if (!ctx)\n    throw new Error(\n      \"getRequest must be called from within a React Server render context\",\n    );\n  return ctx.request;\n}\n\nexport const redirect: typeof baseRedirect = (...args) => {\n  const response = baseRedirect(...args);\n\n  const ctx = ServerStorage.getStore();\n  if (ctx && ctx.runningAction) {\n    ctx.redirect = response;\n  }\n\n  return response;\n};\n\nexport const redirectDocument: typeof baseRedirectDocument = (...args) => {\n  const response = baseRedirectDocument(...args);","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/remix-run/react-router/blob/7aea711dd1ae2bc5a076d13ff17291829690fa74/packages/react-router/lib/rsc/server.rsc.ts#L80-L116","documentation":"In RSC mode, getRequest() reads the current Request from an AsyncLocalStorage store populated while the RSC server handles the request. Outside that scope there is no store, so getRequest() (lib/rsc/server.rsc.ts:98) throws to tell you it was called detached from any server render context.","triggerScenarios":"Calling getRequest() at module scope or during server startup; inside setTimeout/queueMicrotask/setImmediate callbacks that outlived the request context; in a helper invoked from a custom route handler outside the RSC pipeline; after awaiting something that swaps the async context.","commonSituations":"Logging/metrics helpers that 'grab' the request globally instead of receiving it; background jobs kicked off from a server action; refactoring loaders to use a global request accessor.","solutions":["Call getRequest() only inside loaders/actions/middleware or during RSC render","Thread the request explicitly (args.request) into helpers rather than using the global accessor","Capture getRequest() early in the same async scope and close over the result before detaching async work"],"exampleFix":"// before\nasync function logPath() { console.log(getRequest().url) }\nsetTimeout(() => logPath(), 100) // throws: no store\n// after\nconst url = getRequest().url // inside the loader\nsetTimeout(() => console.log(url), 100)","handlingStrategy":"fallback","validationCode":"// Prefer explicit threading; when you must use the global, verify scope first\nfunction currentRequest(): Request | null {\n  try { return getRequest() } catch { return null }\n}\nconst req = currentRequest() ?? explicitRequestArg; // caller-supplied fallback","typeGuard":null,"tryCatchPattern":"try {\n  const request = getRequest();\n} catch (e) {\n  if (e instanceof Error && e.message.includes('React Server render context')) {\n    // no request scope: skip request-scoped work or require the request as a parameter\n  } else throw e;\n}","preventionTips":["Pass args.request explicitly into helpers instead of global accessors","Only call getRequest() inside loaders/actions/middleware or RSC render","Capture request data before detaching async work (setTimeout, queues)"],"tags":["rsc","server","request-context","asynclocalstorage"],"backgroundTag":"async-context-lost","analyzedSha":"7aea711dd1ae2bc5a076d13ff17291829690fa74","analyzedAt":"2026-08-18T18:04:14.938Z","contentChangedAt":"2026-08-18T18:04:14.938Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}