remix-run/react-router · error · Error

getRequest must be called from within a React Server render

Error message

getRequest must be called from within a React Server render context

What it means

`getRequest()` reads the current `Request` from an `AsyncLocalStorage`-backed server context. If `ServerStorage.getStore()` returns `undefined`, the call is outside any `run(...)` scope established by React Router's RSC runtime, so there is no current request and the function refuses to continue.

Source

Thrown at packages/react-router/lib/rsc/server.rsc.ts:98

type ServerContext = {
  redirect?: Response;
  request: Request;
  runningAction: boolean;
};

const globalVar = (typeof globalThis !== "undefined" ? globalThis : global) as {
  ___reactRouterServerStorage___?: AsyncLocalStorage<ServerContext>;
};

const ServerStorage = (globalVar.___reactRouterServerStorage___ ??=
  new AsyncLocalStorage<ServerContext>());

export function getRequest() {
  const ctx = ServerStorage.getStore();

  if (!ctx)
    throw new Error(
      "getRequest must be called from within a React Server render context",
    );
  return ctx.request;
}

export const redirect: typeof baseRedirect = (...args) => {
  const response = baseRedirect(...args);

  const ctx = ServerStorage.getStore();
  if (ctx && ctx.runningAction) {
    ctx.redirect = response;
  }

  return response;
};

export const redirectDocument: typeof baseRedirectDocument = (...args) => {
  const response = baseRedirectDocument(...args);

View on GitHub (pinned to 1fd704a7da)

Solutions

  1. Only call `getRequest()` from inside a server component, loader, action, or middleware running within the RSC render pass.
  2. If you need the request in a helper, accept it as a parameter from the loader/action rather than reading it implicitly.
  3. Confirm the RSC runtime is actually initialized (RSC Framework or RSC Data mode) — in non-RSC modes there is no server context.

Example fix

// before (module scope)
const req = getRequest(); // throws

// after (inside server component)
export default async function Route() {
  const req = getRequest();
  return <pre>{req.url}</pre>;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Only call inside the render pass; gate with an explicit flag
async function safeGetRequest() {
  try {
    return getRequest();
  } catch {
    return undefined;
  }
}

Type guard

function isInServerContext(): boolean {
  return Boolean((globalThis as any).___reactRouterServerStorage___?.getStore?.());
}

Try / catch

let request: Request | undefined;
try {
  request = getRequest();
} catch {
  request = undefined; // not in an RSC render scope
}

Prevention

When it happens

Trigger: Calling `getRequest()` (or RSC-aware `redirect`/`replace` that internally relies on it) at module top-level, in a utility called outside the React Server render pass, or in a worker/thread that doesn't inherit the AsyncLocalStorage context.

Common situations: Calling `getRequest()` from a standalone script, a route module's module scope (not inside loader/action/server component), or a non-RSC handler; using the RSC server API in a Data-mode or Declarative-mode app where no server render context is ever established.

Related errors


AI-assisted analysis of remix-run/react-router@1fd704a7da (2026-08-12). Data as JSON: /api/errors/298324e4343e21d0. Report an issue: GitHub.