remix-run/react-router · error

Cannot handle enhanced server action without decodeReply…

Error message

Cannot handle enhanced server action without decodeReply and loadServerAction functions

What it means

Enhanced (JS-invoked) server actions arrive with an rsc-action-id header and must be decoded with React's decodeReply and resolved with loadServerAction. If the RSC server handler was created without those functions, processServerAction throws (lib/rsc/server.rsc.ts:679) because it has no way to reconstruct the action from the payload.

Solutions

  1. Pass decodeReply and loadServerAction (from your RSC build output / vite RSC plugin runtime) into the server handler options
  2. Prefer the framework-provided server wiring which supplies these functions for you
  3. If you intend to support only form-based actions, prevent the client from sending rsc-action-id requests

Example fix

// before
const handler = createRequestHandler({ build }) // no decode functions
// after
const handler = createRequestHandler({
  build,
  decodeReply,
  loadServerAction,
  decodeAction,
})
Defensive patterns

Strategy: validation

Validate before calling

// Fail fast at server startup instead of on the first action request
const required = { decodeReply, loadServerAction, decodeAction };
for (const [name, fn] of Object.entries(required)) {
  if (typeof fn !== 'function') throw new Error(`RSC handler misconfigured: missing ${name}`);
}

Prevention

When it happens

Trigger: A hand-wired RSC server calling the request handler without passing decodeReply/loadServerAction options; the client sends a fetch-based action request (JS enabled, rsc-action-id header present); partial wiring copied from an example that only covered RSC rendering.

Common situations: Custom RSC Data-mode setups (manual bundler config) missing the decode functions exported by the RSC build/plugin; version upgrades where the handler's option set changed and new functions are required.

Related errors


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

Appendix: source

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

      formState?: ReactFormState;
    }
  | Response
  | undefined
> {
  const getRevalidationRequest = () =>
    new Request(request.url, {
      method: "GET",
      headers: request.headers,
      signal: request.signal,
    });

  const isFormRequest = canDecodeWithFormData(
    request.headers.get("Content-Type"),
  );
  const actionId = request.headers.get("rsc-action-id");
  if (actionId) {
    if (!decodeReply || !loadServerAction) {
      throw new Error(
        "Cannot handle enhanced server action without decodeReply and loadServerAction functions",
      );
    }

    const reply = isFormRequest
      ? await request.formData()
      : await request.text();

    const actionArgs = await decodeReply(reply, { temporaryReferences });
    const action = await loadServerAction(actionId);
    const serverAction = action.bind(null, ...actionArgs);

    let actionResult = Promise.resolve(serverAction());
    try {
      // Wait for actions to finish regardless of state
      await actionResult;
    } catch (error) {
      if (isResponse(error)) {

View on GitHub (pinned to 7aea711dd1)