{"record":{"id":"b3cfa253d85014b5","repo":"remix-run/react-router","slug":"cannot-handle-form-actions-without-a-decodeaction","errorCode":null,"errorMessage":"Cannot handle form actions without a decodeAction function","messagePattern":"Cannot handle form actions without a decodeAction function","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-router/lib/rsc/server.rsc.ts","lineNumber":723,"sourceCode":"    let formData =\n      maybeFormData &&\n      typeof maybeFormData === \"object\" &&\n      maybeFormData instanceof FormData\n        ? maybeFormData\n        : null;\n\n    let skipRevalidation = formData?.has(\"$SKIP_REVALIDATION\") ?? false;\n\n    return {\n      actionResult,\n      revalidationRequest: getRevalidationRequest(),\n      skipRevalidation,\n    };\n  } else if (isFormRequest) {\n    const formData = await request.clone().formData();\n    if (Array.from(formData.keys()).some((k) => k.startsWith(\"$ACTION_\"))) {\n      if (!decodeAction) {\n        throw new Error(\n          \"Cannot handle form actions without a decodeAction function\",\n        );\n      }\n      const action = await decodeAction(formData);\n      let formState = undefined;\n      try {\n        let result = await action();\n        if (isRedirectResponse(result)) {\n          result = prependBasenameToRedirectResponse(result, basename);\n        }\n        formState = await decodeFormState?.(result, formData);\n      } catch (error) {\n        if (isRedirectResponse(error)) {\n          return prependBasenameToRedirectResponse(error, basename);\n        }\n        if (isResponse(error)) {\n          return error;\n        }","sourceCodeStart":705,"sourceCodeEnd":741,"githubUrl":"https://github.com/remix-run/react-router/blob/1fd704a7dabcbe3ae09d7387b460e6acaba30ec1/packages/react-router/lib/rsc/server.rsc.ts#L705-L741","documentation":"`handleServerAction` got a form-encoded request whose keys include `$ACTION_*` (React's form-state action protocol), which means a progressive-enhancement form action needs to be decoded. The runtime refused because `decodeAction` was not provided, so it cannot reconstruct the action callable from the formData.","triggerScenarios":"A POST hits `handleServerAction` from a `<form action>` (or `useFormState`/`useFormStatus`) submission carrying `$ACTION_ID`/`$ACTION_REF`/etc. keys, but the caller did not supply `decodeAction` from `react-server-dom-xyz/server`.","commonSituations":"RSC setup that wired enhanced actions (`decodeReply`+`loadServerAction`) but forgot the form-action decoder; mixing a custom form handler with the RSC handler; mismatched versions where `decodeAction` isn't exported under the expected name.","solutions":["Pass `decodeAction` (and ideally `decodeFormState`) from your `react-server-dom-*/server` module when constructing the RSC request handler.","Make sure the rsd version matches React Router's RSC runtime version so all four decode functions are present.","If you do not use progressive-enhancement form actions, ensure clients send enhanced (rsc-action-id) requests instead, or route forms to a non-RSC endpoint."],"exampleFix":"// before\nhandleServerAction({ request, decodeReply, loadServerAction });\n\n// after\nimport { decodeReply, loadServerAction, decodeAction, decodeFormState } from 'react-server-dom-webpack/server';\nhandleServerAction({ request, decodeReply, loadServerAction, decodeAction, decodeFormState });","handlingStrategy":"validation","validationCode":"function assertFormActionFns(opts: { decodeAction?: unknown }) {\n  if (!opts.decodeAction) throw new Error('Form actions require decodeAction');\n}\nassertFormActionFns({ decodeAction });","typeGuard":"function hasFormActionFns(o: any): o is { decodeAction: Function } {\n  return typeof o.decodeAction === 'function';\n}","tryCatchPattern":null,"preventionTips":["Pass `decodeAction` (and `decodeFormState`) when constructing the RSC request handler.","Match rsd and React Router RSC runtime versions.","If you don't support form actions, ensure clients don't submit `$ACTION_*` form data."],"tags":["rsc","form-actions","config","decode"],"backgroundTag":null,"analyzedSha":"1fd704a7dabcbe3ae09d7387b460e6acaba30ec1","analyzedAt":"2026-08-12T13:54:57.804Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}