{"record":{"id":"344fe41c77d93ba5","repo":"remix-run/react-router","slug":"cannot-handle-enhanced-server-action-without-decod","errorCode":null,"errorMessage":"Cannot handle enhanced server action without decodeReply and loadServerAction functions","messagePattern":"Cannot handle enhanced server action without decodeReply and loadServerAction functions","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/react-router/lib/rsc/server.rsc.ts","lineNumber":686,"sourceCode":"      formState?: ReactFormState;\n    }\n  | Response\n  | undefined\n> {\n  const getRevalidationRequest = () =>\n    new Request(request.url, {\n      method: \"GET\",\n      headers: request.headers,\n      signal: request.signal,\n    });\n\n  const isFormRequest = canDecodeWithFormData(\n    request.headers.get(\"Content-Type\"),\n  );\n  const actionId = request.headers.get(\"rsc-action-id\");\n  if (actionId) {\n    if (!decodeReply || !loadServerAction) {\n      throw new Error(\n        \"Cannot handle enhanced server action without decodeReply and loadServerAction functions\",\n      );\n    }\n\n    const reply = isFormRequest\n      ? await request.formData()\n      : await request.text();\n\n    const actionArgs = await decodeReply(reply, { temporaryReferences });\n    const action = await loadServerAction(actionId);\n    const serverAction = action.bind(null, ...actionArgs);\n\n    let actionResult = Promise.resolve(serverAction());\n    try {\n      // Wait for actions to finish regardless of state\n      await actionResult;\n    } catch (error) {\n      if (isResponse(error)) {","sourceCodeStart":668,"sourceCodeEnd":704,"githubUrl":"https://github.com/remix-run/react-router/blob/7aea711dd1ae2bc5a076d13ff17291829690fa74/packages/react-router/lib/rsc/server.rsc.ts#L668-L704","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pass decodeReply and loadServerAction (from your RSC build output / vite RSC plugin runtime) into the server handler options","Prefer the framework-provided server wiring which supplies these functions for you","If you intend to support only form-based actions, prevent the client from sending rsc-action-id requests"],"exampleFix":"// before\nconst handler = createRequestHandler({ build }) // no decode functions\n// after\nconst handler = createRequestHandler({\n  build,\n  decodeReply,\n  loadServerAction,\n  decodeAction,\n})","handlingStrategy":"validation","validationCode":"// Fail fast at server startup instead of on the first action request\nconst required = { decodeReply, loadServerAction, decodeAction };\nfor (const [name, fn] of Object.entries(required)) {\n  if (typeof fn !== 'function') throw new Error(`RSC handler misconfigured: missing ${name}`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Wire decodeReply/loadServerAction/decodeAction from the RSC build runtime when creating a custom server","Prefer framework-provided server entry points that supply these functions","Add a startup assertion listing required handler options","Exercise one JS action and one no-JS form POST in smoke tests before shipping"],"tags":["rsc","server-actions","configuration","decode-reply"],"backgroundTag":"missing-rsc-handler-config","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"}