{"record":{"id":"d2a962c59ee8feec","repo":"facebook/react","slug":"server-actions-must-be-functions-d2a962","errorCode":null,"errorMessage":"Server actions must be functions","messagePattern":"Server actions must be functions","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-server-dom-parcel/src/server/ReactFlightDOMServerEdge.js","lineNumber":345,"sourceCode":"export function decodeAction<T>(body: FormData): Promise<() => T> | null {\n  return decodeActionImpl(body, serverManifest);\n}\n\nexport function decodeFormState<S>(\n  actionResult: S,\n  body: FormData,\n): Promise<ReactFormState<S, ServerReferenceId> | null> {\n  return decodeFormStateImpl(actionResult, body, serverManifest);\n}\n\nexport function loadServerAction<F: (...any[]) => any>(id: string): Promise<F> {\n  const reference = resolveServerReference<any>(serverManifest, id);\n  return Promise.resolve(reference)\n    .then(() => preloadModule(reference))\n    .then(() => {\n      const fn = requireModule(reference);\n      if (typeof fn !== 'function') {\n        throw new Error('Server actions must be functions');\n      }\n      return fn;\n    });\n}\n","sourceCodeStart":327,"sourceCodeEnd":350,"githubUrl":"https://github.com/facebook/react/blob/eafeac097ba51e1eab809c07102126bd5f8e5425/packages/react-server-dom-parcel/src/server/ReactFlightDOMServerEdge.js#L327-L350","documentation":"In the edge-build server writer for Parcel, loadServerAction resolves the action id against the server manifest, preloads its bundles, then requires the module and checks the binding is a function before invoking it. A missing export (stale name) or a non-function export fails the check and throws at request time.","triggerScenarios":"A 'use server' module whose referenced export is missing or not a function: renamed export without a manifest rebuild, a const/object/class exported from the actions file, or a bundle that fails to expose the named binding.","commonSituations":"Refactors renaming exports while the edge manifest stays stale; mixing config constants into 'use server' files; divergent builds between manifest and action modules.","solutions":["Ensure every export of a 'use server' file is an async function","Rebuild manifest and bundles together after any export rename","Assert in CI that every manifest-referenced export resolves to a function"],"exampleFix":"// before — non-function export reachable via the action id\n'use server';\nexport const revalidate = 60; // stale manifest points 'content#revalidate' here\n\n// after — actions are functions only; config lives elsewhere\n'use server';\nexport async function revalidate() { /* ... */ }","handlingStrategy":"validation","validationCode":"// dev/CI check: every export of a 'use server' module must be a function\nimport * as actions from './app-actions';\nfor (const [name, value] of Object.entries(actions)) {\n  if (typeof value !== 'function') {\n    throw new Error(`app-actions exports non-function '${name}'`);\n  }\n}","typeGuard":"export function isServerActionExport(mod, name) {\n  const value = mod[name];\n  return typeof value === 'function';\n}","tryCatchPattern":"try {\n  await loadServerAction(id);\n} catch (e) {\n  if (/Server actions must be functions/.test(e.message)) {\n    // return a 500 and alert: manifest name does not resolve to a function export\n    return new Response('Action unavailable', {status: 500});\n  }\n  throw e;\n}","preventionTips":["Export only async functions from 'use server' files","Regenerate the edge manifest in the same build step as the action modules","Validate manifest names against module exports before deploying"],"tags":["react-server-components","server-actions","parcel","edge","exports"],"backgroundTag":"server-action-export-not-function","analyzedSha":"eafeac097ba51e1eab809c07102126bd5f8e5425","analyzedAt":"2026-08-21T22:01:08.818Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}