remix-run/react-router · error

Prerender (resource): Received a

Error message

Prerender (resource): Received a ${response.status} status code from `entry.server.tsx` while prerendering the `${pathname}` path.
${new TextDecoder().decode(contents)}

What it means

When prerendering a resource route (a route with no default export, like `routes/robots[.]txt.ts`), React Router requests it from the built server and requires a 200 response. Any other status means the resource route handler failed while generating static output. The error message embeds the decoded response body so you can see the server-side error text.

Solutions

  1. Run the resource route handler directly (or hit the dev server URL) to reproduce the failure and fix the thrown error
  2. Make build-time dependencies resilient: guard the external call, cache the result, or commit static content and serve it directly instead of prerendering
  3. Ensure required environment variables are set in the build/CI environment, not only at runtime
  4. Drop the resource route from the `prerender` list and generate the file with a script if it cannot succeed at build time

Example fix

// before (app/routes/sitemap[.]xml.ts)
export async function loader() {
  let res = await fetch('https://api.example.com/pages');
  if (!res.ok) throw new Response('upstream failed', { status: 502 });
  return new Response(await res.text());
}

// after — degrade gracefully at build time
export async function loader() {
  let res = await fetch('https://api.example.com/pages');
  if (!res.ok) {
    return new Response('<?xml version="1.0"?><urlset></urlset>', {
      headers: { 'Content-Type': 'application/xml' },
    });
  }
  return new Response(await res.text());
}
Defensive patterns

Strategy: validation

Validate before calling

// Dry-run a resource route before prerendering it
const res = await fetch(`http://localhost:3000/robots.txt`);
if (!res.ok) {
  throw new Error(`Refusing to prerender /robots.txt — dev server returned ${res.status}`);
}

Try / catch

try {
  await build();
} catch (e) {
  if (e instanceof Error && /^Prerender \(resource\)/.test(e.message)) {
    // message already embeds the decoded response body — surface it in CI logs
    console.error(e.message);
  }
}

Prevention

When it happens

Trigger: A resource route listed in `prerender` whose handler throws (e.g. external fetch failure during build); a resource route returning `json(..., { status: 500 })`; a resource route relying on runtime-only context (env vars, request cookies) that is absent during the build-time request.

Common situations: Prerendering `robots.txt`, `sitemap.xml`, or RSS feeds whose handlers call slow or rate-limited third-party APIs; resource routes reading `process.env` keys that exist in deploy but not in CI; handlers that redirect (3xx) which are not valid static files.

Related errors


AI-assisted analysis of remix-run/react-router@6beaca3952 (2026-08-18). Data as JSON: /api/errors/141b481dc62e5a41. Report an issue: GitHub.

Appendix: source

Thrown at packages/react-router-dev/vite/plugin.ts:2585

                path: pathname,
                contents: data,
              },
            ],
            // After saving the .data file, request the HTML page.
            // The data is passed along to be embedded in the response header.
            requests: !metadata.isResourceRoute
              ? [createRouteRequest(metadata.path, ctx.reactRouterConfig, data)]
              : [],
          };
        }

        // Handle resource route responses
        if (metadata.type === "resource") {
          let pathname = new URL(request.url).pathname;
          let contents = new Uint8Array(await response.arrayBuffer());

          if (response.status !== 200) {
            throw new Error(
              `Prerender (resource): Received a ${response.status} status code from ` +
                `\`entry.server.tsx\` while prerendering the \`${pathname}\` ` +
                `path.\n${new TextDecoder().decode(contents)}`,
            );
          }

          return [
            {
              path: pathname,
              contents,
            },
          ];
        }

        // Handle document responses (html or spa)
        let html = await response.text();

        if (metadata.type === "spa") {

View on GitHub (pinned to 6beaca3952)