remix-run/react-router · error · Error

Unexpected payload type

Error message

Unexpected payload type

What it means

After invoking a server action, the RSC client decodes the returned payload and requires its `type` to be `"action"` (with `actionResult`) or `"redirect"`. Anything else — typically a `"render"` navigation payload or a `"manifest"` payload — throws this error. It almost always means the POST was not processed as an action call by the server, so the shape the client got does not match the action protocol.

Source

Thrown at packages/react-router/lib/rsc/browser.tsx:246

                  ),
                  errors: rerender.errors
                    ? Object.assign(
                        {},
                        globalVar.__reactRouterDataRouter.state.errors,
                        rerender.errors,
                      )
                    : null,
                },
              );
            });
          }
        })
        .catch(() => {}),
    );

    return payloadPromise.then((payload) => {
      if (payload.type !== "action" && payload.type !== "redirect") {
        throw new Error("Unexpected payload type");
      }

      return payload.actionResult;
    });
  };
}

function createRouterFromPayload({
  fetchImplementation,
  createFromReadableStream,
  getContext,
  payload,
}: {
  payload: RSCPayload;
  createFromReadableStream: BrowserCreateFromReadableStreamFunction;
  fetchImplementation: (request: Request) => Promise<Response>;
  getContext: RouterInit["getContext"] | undefined;
}): {

View on GitHub (pinned to 7aea711dd1)

Solutions

  1. Verify the `rsc-action-id` request header survives every proxy/CDN/service-worker hop and reaches your server.
  2. Rule out version skew: hard reload after deploys, and keep client/server built from the same artifact.
  3. If you have a custom server, ensure requests with `rsc-action-id` are handled by the RSC action pipeline, not the document/SSR pipeline.
  4. Log the received payload `type` temporarily to identify which interceptor is changing the response.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await submitServerAction();
} catch (e) {
  if (e instanceof Error && e.message === "Unexpected payload type") {
    window.location.reload(); // typically version skew after a deploy
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: A proxy or service worker stripping the `rsc-action-id` header, so the server treats the request as a normal navigation and returns a render payload; version skew where an old client sends action ids a new server no longer resolves to actions; custom servers routing RSC POSTs to the wrong handler.

Common situations: Reverse proxies (nginx/Cloudflare workers) dropping custom headers; auth layers that redirect POSTs into GET navigations; mid-deploy requests where client and server action manifests disagree.

Related errors


AI-assisted analysis of remix-run/react-router@7aea711dd1 (2026-08-18). Data as JSON: /api/errors/444413139b1d15c1. Report an issue: GitHub.