javascriptreactjsnext.js

TypeError: Cannot read properties of undefined (reading 'bind') in RSC action


It's a Next.js v15 app with React v19 where I want to get benefits from the action property in a form. This ensures the form could be submitted even when the JavaScript is disabled on the browser.

The problem is that when I keep the relevant function inside the same server component, everything works. But, if I export the relevant function from a separate action.ts file, it doesn't work.

For example, the following works:

import { authClient } from "@/lib/auth-client";

export default function SignInPage() {
  const abc = async () => {
    "use server";
    const { data, error } = await authClient.signUp.email({
      email: "hello@example.com",
      password: "password",
      name: "John Doe",
    });

    console.log(data, error);
  };

  return (
    <form
      action={async (formData: FormData) => {
        "use server";
        abc();
      }}
    >
      <input type="email" name="email" placeholder="Email" />
      <input type="password" name="password" placeholder="Password" />
      <button type="submit">Sign In</button>
    </form>
  );
}

As soon as I move the abc() function in a separate file, it doesn't work:

'use server'

export const abc = async () => {
  "use server";
  const { data, error } = await authClient.signUp.email({
    email: "hello@example.com",
    password: "password",
    name: "John Doe",
  });

  console.log(data, error);
};

It throws the following error:

 GET /test 200 in 68ms
 GET /favicon.ico?favicon.45db1c09.ico 200 in 60ms
 ⨯ TypeError: Cannot read properties of undefined (reading 'bind')
    at bind (webpack://next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js:3713:22)
    at async (webpack://next/dist/src/server/app-render/action-handler.ts:797:27)
    at async handleAction (webpack://next/dist/src/server/app-render/action-handler.ts:617:4)
    at async renderToHTMLOrFlightImpl (webpack://next/dist/src/server/app-render/app-render.tsx:1310:34)
    at async doRender (node_modules/.pnpm/next@15.0.4_react-dom@19.0.0_react@19.0.0__react@19.0.0/node_modules/next/src/server/base-server.ts:2666:21)
    at async responseGenerator (node_modules/.pnpm/next@15.0.4_react-dom@19.0.0_react@19.0.0__react@19.0.0/node_modules/next/src/server/base-server.ts:3027:21)
    at async DevServer.renderToResponseWithComponentsImpl (node_modules/.pnpm/next@15.0.4_react-dom@19.0.0_react@19.0.0__react@19.0.0/node_modules/next/src/server/base-server.ts:3039:23)
    at async DevServer.renderPageComponent (node_modules/.pnpm/next@15.0.4_react-dom@19.0.0_react@19.0.0__react@19.0.0/node_modules/next/src/server/base-server.ts:3597:15)
    at async DevServer.renderToResponseImpl (node_modules/.pnpm/next@15.0.4_react-dom@19.0.0_react@19.0.0__react@19.0.0/node_modules/next/src/server/base-server.ts:3659:23)
    at async DevServer.pipeImpl (node_modules/.pnpm/next@15.0.4_react-dom@19.0.0_react@19.0.0__react@19.0.0/node_modules/next/src/server/base-server.ts:1698:20)
    at async NextNodeServer.handleCatchallRenderRequest (node_modules/.pnpm/next@15.0.4_react-dom@19.0.0_react@19.0.0__react@19.0.0/node_modules/next/src/server/next-server.ts:1034:6)
    at async DevServer.handleRequestImpl (node_modules/.pnpm/next@15.0.4_react-dom@19.0.0_react@19.0.0__react@19.0.0/node_modules/next/src/server/base-server.ts:1462:8)
    at async (node_modules/.pnpm/next@15.0.4_react-dom@19.0.0_react@19.0.0__react@19.0.0/node_modules/next/src/server/dev/next-dev-server.ts:514:13)
    at async Span.traceAsyncFn (node_modules/.pnpm/next@15.0.4_react-dom@19.0.0_react@19.0.0__react@19.0.0/node_modules/next/src/trace/trace.ts:143:13)
    at async DevServer.handleRequest (node_modules/.pnpm/next@15.0.4_react-dom@19.0.0_react@19.0.0__react@19.0.0/node_modules/next/src/server/dev/next-dev-server.ts:512:19)
    at async invokeRender (node_modules/.pnpm/next@15.0.4_react-dom@19.0.0_react@19.0.0__react@19.0.0/node_modules/next/src/server/lib/router-server.ts:284:10)
    at async handleRequest (node_modules/.pnpm/next@15.0.4_react-dom@19.0.0_react@19.0.0__react@19.0.0/node_modules/next/src/server/lib/router-server.ts:530:15)
    at async requestHandlerImpl (node_modules/.pnpm/next@15.0.4_react-dom@19.0.0_react@19.0.0__react@19.0.0/node_modules/next/src/server/lib/router-server.ts:576:6)
    at async Server.requestListener (node_modules/.pnpm/next@15.0.4_react-dom@19.0.0_react@19.0.0__react@19.0.0/node_modules/next/src/server/lib/start-server.ts:146:6)
  795 |             })
  796 |             const formData = await fakeRequest.formData()
> 797 |             const action = await decodeAction(formData, serverModuleMap)
      |                           ^
  798 |             if (typeof action === 'function') {
  799 |               // Only warn if it's a server action, otherwise skip for other post requests
  800 |               warnBadServerActionRequest() {
  page: '/test'
}
 POST /test 500 in 282ms

I need to separate the abc() function in a separate file. Otherwise, I can't make the SignInPage() a Client component to use React hooks. The authclient() we have is coming from the https://www.better-auth.com/docs/basic-usage#sign-in library. The error isn't specific to authClient but any asynchronous function will throw the error.

Tinkered with a lot but couldn't figure it out. Would appreciate if anyone can show some light on this 🙏


Solution

  • It turns out an issue to my own implementation even though I am pretty sure that I tried the same thing before posting here but that that didn't work before but now it does.

    Anyways, I had to use the correct API from Better Auth and that did it this time:

    await authClient.signUp.email()