[GH-ISSUE #5539] Failed to fetch dynamically imported module: node:async_hooks #10278

Closed
opened 2026-04-13 06:17:48 -05:00 by GiteaMirror · 41 comments
Owner

Originally created by @qweered on GitHub (Oct 24, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/5539

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

I've updated from 1.3.27 to 1.3.29 and saw that error. toNextjsHandler configured correctly. I have proxy.ts file instead of middleware.ts. 1.3.27 with proxy.ts also works correctly, not tested 1.3.29

export async function proxy(request: NextRequest) {
    const session = await auth.api.getSession({
        headers: await headers()
    })

    if (!session) {
        return NextResponse.redirect(new URL('/login', request.url))
    }

    return NextResponse.next()
}

export const config = {
    matcher: ['/dashboard', '/profile', '/settings', '/create-organization', '/invitations']
}

Current vs. Expected behavior

Do not have error

 ✓ Ready in 3.4s
[browser] [better-auth] Warning: AsyncLocalStorage is not available in this environment. Some features may not work as expected. (file:///home/qweered/Projects/automaspec/.next/dev/static/chunks/02ec3_next_dist_91e776ba._.js:2294:13)
[browser] [better-auth] Please read more about this warning at https://better-auth.com/docs/installation#mount-handler (file:///home/qweered/Projects/automaspec/.next/dev/static/chunks/02ec3_next_dist_91e776ba._.js:2294:13)
[browser] [better-auth] If you are using Cloudflare Workers, please see: https://developers.cloudflare.com/workers/configuration/compatibility-flags/#nodejs-compatibility-flag (file:///home/qweered/Projects/automaspec/.next/dev/static/chunks/02ec3_next_dist_91e776ba._.js:2294:13)
[browser] ⨯ unhandledRejection: TypeError: Failed to fetch dynamically imported module: node:async_hooks
TypeError: Failed to fetch dynamically imported module: node:async_hooks

What version of Better Auth are you using?

1.3.29

System info

{
  "system": {
    "platform": "linux",
    "arch": "x64",
    "version": "#1-NixOS SMP PREEMPT_DYNAMIC Wed Oct 15 10:04:23 UTC 2025",
    "release": "6.17.3-cachyos",
    "cpuCount": 8,
    "cpuModel": "AMD Ryzen 3 5300U with Radeon Graphics",
    "totalMemory": "14.95 GB",
    "freeMemory": "5.20 GB"
  },
  "node": {
    "version": "v22.19.0",
    "env": "development"
  },
  "packageManager": {
    "name": "pnpm",
    "version": "10.18.3"
  },
  "frameworks": [
    {
      "name": "next",
      "version": "16.0.0"
    },
    {
      "name": "react",
      "version": "19.2.0"
    }
  ],
  "databases": [
    {
      "name": "@libsql/client",
      "version": "^0.15.15"
    },
    {
      "name": "drizzle",
      "version": "^0.44.7"
    }
  ],
  "betterAuth": {
    "version": "1.3.27",
    "config": null
  }
}

Which area(s) are affected? (Select all that apply)

Client

Auth config (if applicable)

export const auth = betterAuth({
    database: drizzleAdapter(db, {
        provider: 'sqlite',
        schema: schema
    }),
    trustedOrigins: [...(process.env.VERCEL_URL ? [`https://${process.env.VERCEL_URL}`] : [])],
    emailAndPassword: {
        enabled: true
    },
    plugins: [
        organization({
            allowUserToCreateOrganization: true,
            organizationLimit: 1,
            membershipLimit: 1,
            creatorRole: 'owner'
        })
    ]
})

export const authClient = createAuthClient({
    baseURL: typeof window !== 'undefined' ? window.location.origin : undefined,
    plugins: [
        organizationClient({
            schema: inferOrgAdditionalFields<typeof auth>()
        })
    ]
})

Additional context

No response

Originally created by @qweered on GitHub (Oct 24, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/5539 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce I've updated from 1.3.27 to 1.3.29 and saw that error. toNextjsHandler configured correctly. I have proxy.ts file instead of middleware.ts. 1.3.27 with proxy.ts also works correctly, not tested 1.3.29 ```ts export async function proxy(request: NextRequest) { const session = await auth.api.getSession({ headers: await headers() }) if (!session) { return NextResponse.redirect(new URL('/login', request.url)) } return NextResponse.next() } export const config = { matcher: ['/dashboard', '/profile', '/settings', '/create-organization', '/invitations'] } ``` ### Current vs. Expected behavior Do not have error ```bash ✓ Ready in 3.4s [browser] [better-auth] Warning: AsyncLocalStorage is not available in this environment. Some features may not work as expected. (file:///home/qweered/Projects/automaspec/.next/dev/static/chunks/02ec3_next_dist_91e776ba._.js:2294:13) [browser] [better-auth] Please read more about this warning at https://better-auth.com/docs/installation#mount-handler (file:///home/qweered/Projects/automaspec/.next/dev/static/chunks/02ec3_next_dist_91e776ba._.js:2294:13) [browser] [better-auth] If you are using Cloudflare Workers, please see: https://developers.cloudflare.com/workers/configuration/compatibility-flags/#nodejs-compatibility-flag (file:///home/qweered/Projects/automaspec/.next/dev/static/chunks/02ec3_next_dist_91e776ba._.js:2294:13) [browser] ⨯ unhandledRejection: TypeError: Failed to fetch dynamically imported module: node:async_hooks TypeError: Failed to fetch dynamically imported module: node:async_hooks ``` ### What version of Better Auth are you using? 1.3.29 ### System info ```bash { "system": { "platform": "linux", "arch": "x64", "version": "#1-NixOS SMP PREEMPT_DYNAMIC Wed Oct 15 10:04:23 UTC 2025", "release": "6.17.3-cachyos", "cpuCount": 8, "cpuModel": "AMD Ryzen 3 5300U with Radeon Graphics", "totalMemory": "14.95 GB", "freeMemory": "5.20 GB" }, "node": { "version": "v22.19.0", "env": "development" }, "packageManager": { "name": "pnpm", "version": "10.18.3" }, "frameworks": [ { "name": "next", "version": "16.0.0" }, { "name": "react", "version": "19.2.0" } ], "databases": [ { "name": "@libsql/client", "version": "^0.15.15" }, { "name": "drizzle", "version": "^0.44.7" } ], "betterAuth": { "version": "1.3.27", "config": null } } ``` ### Which area(s) are affected? (Select all that apply) Client ### Auth config (if applicable) ```typescript export const auth = betterAuth({ database: drizzleAdapter(db, { provider: 'sqlite', schema: schema }), trustedOrigins: [...(process.env.VERCEL_URL ? [`https://${process.env.VERCEL_URL}`] : [])], emailAndPassword: { enabled: true }, plugins: [ organization({ allowUserToCreateOrganization: true, organizationLimit: 1, membershipLimit: 1, creatorRole: 'owner' }) ] }) export const authClient = createAuthClient({ baseURL: typeof window !== 'undefined' ? window.location.origin : undefined, plugins: [ organizationClient({ schema: inferOrgAdditionalFields<typeof auth>() }) ] }) ``` ### Additional context _No response_
GiteaMirror added the locked label 2026-04-13 06:17:48 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Oct 24, 2025):

This error is caused by Better Auth's use of Node.js built-in modules (like async_hooks for AsyncLocalStorage) in versions 1.3.5 and later. These modules aren't available in some environments, such as certain Next.js middleware/proxy setups or edge runtimes, which triggers the "Failed to fetch dynamically imported module: node:async_hooks" error and the AsyncLocalStorage warning. This is not directly related to using proxy.ts instead of middleware.ts—the root issue is environment compatibility with Node.js APIs, not the filename or handler type.

Disabling telemetry via config or env vars does not fully resolve this, because the imports still happen in affected versions. A fix to guard these imports was merged but is not included in 1.3.29 yet. The only reliable workarounds for now are to downgrade to v1.3.4 or patch the code to avoid unconditional Node.js imports citation.

For Next.js middleware/proxy, using getSessionCookie instead of auth.api.getSession is recommended for better compatibility and to avoid unnecessary database calls citation.

If you need to stay on 1.3.29, you’ll need to wait for a release that includes the fix, or apply a patch to guard Node.js imports in your local copy.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

<!-- gh-comment-id:3442662101 --> @dosubot[bot] commented on GitHub (Oct 24, 2025): <!-- Answer --> This error is caused by Better Auth's use of Node.js built-in modules (like `async_hooks` for `AsyncLocalStorage`) in versions 1.3.5 and later. These modules aren't available in some environments, such as certain Next.js middleware/proxy setups or edge runtimes, which triggers the "Failed to fetch dynamically imported module: node:async_hooks" error and the AsyncLocalStorage warning. This is not directly related to using `proxy.ts` instead of `middleware.ts`—the root issue is environment compatibility with Node.js APIs, not the filename or handler type. Disabling telemetry via config or env vars does not fully resolve this, because the imports still happen in affected versions. A fix to guard these imports was merged but is not included in 1.3.29 yet. The only reliable workarounds for now are to downgrade to v1.3.4 or patch the code to avoid unconditional Node.js imports [citation](https://github.com/better-auth/better-auth/issues/3998). For Next.js middleware/proxy, using `getSessionCookie` instead of `auth.api.getSession` is recommended for better compatibility and to avoid unnecessary database calls [citation](https://github.com/better-auth/better-auth/issues/2143). If you need to stay on 1.3.29, you’ll need to wait for a release that includes the fix, or apply a patch to guard Node.js imports in your local copy. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/60480c42-c46c-436a-8555-bfd01a74f82a?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/60480c42-c46c-436a-8555-bfd01a74f82a?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/60480c42-c46c-436a-8555-bfd01a74f82a?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/60480c42-c46c-436a-8555-bfd01a74f82a?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/60480c42-c46c-436a-8555-bfd01a74f82a?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/60480c42-c46c-436a-8555-bfd01a74f82a?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/60480c42-c46c-436a-8555-bfd01a74f82a?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/5539)
Author
Owner

@qweered commented on GitHub (Nov 5, 2025):

Fixed

<!-- gh-comment-id:3491942374 --> @qweered commented on GitHub (Nov 5, 2025): Fixed
Author
Owner

@thedevdavid commented on GitHub (Nov 21, 2025):

@qweered it's present in the latest beta 1.4.0-beta.25

<!-- gh-comment-id:3564148072 --> @thedevdavid commented on GitHub (Nov 21, 2025): @qweered it's present in the latest beta `1.4.0-beta.25`
Author
Owner

@soultellegend commented on GitHub (Nov 23, 2025):

I'm still seeing this in better-auth@1.4.1 in a standard Next.js App Router app (Next 15, Node 22, pnpm).

In my case it only happens when I add the Polar adapter client plugin:

import { createAuthClient } from "better-auth/react";
import { polarClient } from "@polar-sh/better-auth";

export const authClient = createAuthClient({
  baseURL: process.env.NEXT_PUBLIC_API_URL || "http://localhost:4000",
  plugins: [polarClient()],
});

As soon as this runs in the browser I get:

Failed to fetch dynamically imported module: node:async_hooks

If I remove polarClient() from the plugins array, the error disappears and everything works as expected. No Cloudflare / edge runtime involved here just a regular Node runtime with Express backend + Next.js frontend.

I’ve opened a related issue on the Polar adapters repo as well, and for now they suggested using the Polar SDK directly for embedded checkout as a workaround. That works for checkout, but it doesn’t cover the extra client methods shown in the Better Auth Polar docs (e.g. authClient.customer.orders.list, authClient.customer.benefits.list, etc.), which rely on the polarClient() plugin being usable on the frontend.

Edit: Yes client functions are working, only problem is console logs Failed to fetch dynamically imported module: node:async_hooks

<!-- gh-comment-id:3567642719 --> @soultellegend commented on GitHub (Nov 23, 2025): I'm still seeing this in `better-auth@1.4.1` in a standard Next.js App Router app (Next 15, Node 22, pnpm). In my case it only happens when I add the Polar adapter client plugin: ```ts import { createAuthClient } from "better-auth/react"; import { polarClient } from "@polar-sh/better-auth"; export const authClient = createAuthClient({ baseURL: process.env.NEXT_PUBLIC_API_URL || "http://localhost:4000", plugins: [polarClient()], }); ``` As soon as this runs in the browser I get: > Failed to fetch dynamically imported module: node:async_hooks If I remove polarClient() from the plugins array, the error disappears and everything works as expected. No Cloudflare / edge runtime involved here just a regular Node runtime with Express backend + Next.js frontend. I’ve opened a related issue on the Polar adapters repo as well, and for now they suggested using the Polar SDK directly for embedded checkout as a workaround. That works for checkout, but it doesn’t cover the extra client methods shown in the Better Auth Polar docs (e.g. authClient.customer.orders.list, authClient.customer.benefits.list, etc.), which rely on the polarClient() plugin being usable on the frontend. Edit: Yes client functions are working, only problem is console logs Failed to fetch dynamically imported module: node:async_hooks
Author
Owner

@rishi-raj-jain commented on GitHub (Nov 23, 2025):

The code of polarClient is available at https://github.com/polarsource/polar-adapters/blob/main/packages/polar-betterauth/src/client.ts.

<!-- gh-comment-id:3567930689 --> @rishi-raj-jain commented on GitHub (Nov 23, 2025): The code of polarClient is available at https://github.com/polarsource/polar-adapters/blob/main/packages/polar-betterauth/src/client.ts.
Author
Owner

@rishi-raj-jain commented on GitHub (Nov 23, 2025):

from this issue

The only issue with using polarClient is the console log error that shows up, the workaround shipped in this PR does solve the issue and allows them to use the methods shown in the Better Auth Polar docs (e.g. authClient.customer.orders.list, authClient.customer.benefits.list, etc.) just fine.

<!-- gh-comment-id:3567969070 --> @rishi-raj-jain commented on GitHub (Nov 23, 2025): > from [this issue](https://github.com/polarsource/polar/issues/8002#issuecomment-3567941747) The only issue with using polarClient is the console log error that shows up, the workaround shipped in [this PR](https://github.com/soultellegend/better-auth-polar-error/pull/1/files) does solve the issue and allows them to use the methods shown in the Better Auth Polar docs (e.g. authClient.customer.orders.list, authClient.customer.benefits.list, etc.) just fine.
Author
Owner

@imqwertyc commented on GitHub (Nov 24, 2025):

Fixed

How??
@qweered

<!-- gh-comment-id:3572669178 --> @imqwertyc commented on GitHub (Nov 24, 2025): > Fixed How?? @qweered
Author
Owner

@qweered commented on GitHub (Nov 24, 2025):

I suppose it was fixed #5555, i updated deps some time ago and error gone

<!-- gh-comment-id:3572937017 --> @qweered commented on GitHub (Nov 24, 2025): I suppose it was fixed #5555, i updated deps some time ago and error gone
Author
Owner

@ijmozn commented on GitHub (Nov 25, 2025):

I suppose it was fixed #5555, i updated deps some time ago and error gone

It's still present for me in latest version 1.4.0

<!-- gh-comment-id:3573817736 --> @ijmozn commented on GitHub (Nov 25, 2025): > I suppose it was fixed #5555, i updated deps some time ago and error gone It's still present for me in latest version 1.4.0
Author
Owner

@shaked-frame commented on GitHub (Nov 25, 2025):

also getting this after bumping to 1.4.1
any idea what causes it? seems like something is trying to cross the server-client boundary

<!-- gh-comment-id:3575469826 --> @shaked-frame commented on GitHub (Nov 25, 2025): also getting this after bumping to 1.4.1 any idea what causes it? seems like something is trying to cross the server-client boundary
Author
Owner

@fcsouza commented on GitHub (Nov 26, 2025):

anyone know how to resolve this error?
version "better-auth": "1.3.33", with the same error

Failed to fetch dynamically imported module: node:async_hooks

<!-- gh-comment-id:3578361126 --> @fcsouza commented on GitHub (Nov 26, 2025): anyone know how to resolve this error? version "better-auth": "1.3.33", with the same error Failed to fetch dynamically imported module: node:async_hooks
Author
Owner

@batpool commented on GitHub (Nov 26, 2025):

anyone know how to resolve this error? version "better-auth": "1.3.33", with the same error

Failed to fetch dynamically imported module: node:async_hooks

same with as well

"better-auth": "^1.4.2",
Image
<!-- gh-comment-id:3579294618 --> @batpool commented on GitHub (Nov 26, 2025): > anyone know how to resolve this error? version "better-auth": "1.3.33", with the same error > > Failed to fetch dynamically imported module: node:async_hooks same with as well ```js "better-auth": "^1.4.2", ``` <img width="677" height="42" alt="Image" src="https://github.com/user-attachments/assets/45e01b6c-a067-4cbd-aa08-a04ff2ff90a7" />
Author
Owner

@maytees commented on GitHub (Nov 26, 2025):

I'm getting the same error here.

<!-- gh-comment-id:3579334744 --> @maytees commented on GitHub (Nov 26, 2025): I'm getting the same error here.
Author
Owner

@batpool commented on GitHub (Nov 26, 2025):

i am getting the error after adding fofopayments

import { dodopaymentsClient } from "@dodopayments/better-auth";

export const authClient = createAuthClient({
  baseURL: process.env.BETTER_AUTH_URL || "http://localhost:3000",
  plugins: [dodopaymentsClient()],
});
<!-- gh-comment-id:3579459820 --> @batpool commented on GitHub (Nov 26, 2025): i am getting the error after adding fofopayments ```ts import { dodopaymentsClient } from "@dodopayments/better-auth"; export const authClient = createAuthClient({ baseURL: process.env.BETTER_AUTH_URL || "http://localhost:3000", plugins: [dodopaymentsClient()], }); ```
Author
Owner

@batpool commented on GitHub (Nov 26, 2025):

https://github.com/better-auth/better-auth/blob/canary/packages/core/src/async_hooks/index.ts

here its not checking for browser or not, it should be skipped in browser

<!-- gh-comment-id:3579788580 --> @batpool commented on GitHub (Nov 26, 2025): https://github.com/better-auth/better-auth/blob/canary/packages/core/src/async_hooks/index.ts here its not checking for browser or not, it should be skipped in browser
Author
Owner

@landoncolburn commented on GitHub (Nov 26, 2025):

I'm also getting this issue when using the polarClient plugin:

import { polarClient } from "@polar-sh/better-auth";
import { createAuthClient } from "better-auth/react";
export const authClient = createAuthClient({
	baseURL: process.env.NEXT_PUBLIC_APP_URL,
	plugins: [polarClient()],
});

When I comment out the polarClient lines, the error goes away.

I've attached my console logs below from the browser:

[Error] Failed to load resource: unsupported URL (node:async_hooks, line 0)
[Warning] [better-auth] Warning: AsyncLocalStorage is not available in this environment. Some features may not work as expected. (7ae12_next_dist_e6700ec0._.js, line 2288)
[Warning] [better-auth] Please read more about this warning at https://better-auth.com/docs/installation#mount-handler (7ae12_next_dist_e6700ec0._.js, line 2288)
[Warning] [better-auth] If you are using Cloudflare Workers, please see: https://developers.cloudflare.com/workers/configuration/compatibility-flags/#nodejs-compatibility-flag (7ae12_next_dist_e6700ec0._.js, line 2288)
[Error] Unhandled Promise Rejection: TypeError: Importing a module script failed.
	(anonymous function) (1ae26_@better-auth_core_dist_2ead24dc._.js:99)

This is running locally with node 22.17.0, next 16.0.4, @polar-sh/better-auth ^1.5.0, better-auth 1.4.2 and chrome 142.0.7444.176

<!-- gh-comment-id:3582934860 --> @landoncolburn commented on GitHub (Nov 26, 2025): I'm also getting this issue when using the polarClient plugin: ```typescript import { polarClient } from "@polar-sh/better-auth"; import { createAuthClient } from "better-auth/react"; export const authClient = createAuthClient({ baseURL: process.env.NEXT_PUBLIC_APP_URL, plugins: [polarClient()], }); ``` When I comment out the polarClient lines, the error goes away. I've attached my console logs below from the browser: ``` [Error] Failed to load resource: unsupported URL (node:async_hooks, line 0) [Warning] [better-auth] Warning: AsyncLocalStorage is not available in this environment. Some features may not work as expected. (7ae12_next_dist_e6700ec0._.js, line 2288) [Warning] [better-auth] Please read more about this warning at https://better-auth.com/docs/installation#mount-handler (7ae12_next_dist_e6700ec0._.js, line 2288) [Warning] [better-auth] If you are using Cloudflare Workers, please see: https://developers.cloudflare.com/workers/configuration/compatibility-flags/#nodejs-compatibility-flag (7ae12_next_dist_e6700ec0._.js, line 2288) [Error] Unhandled Promise Rejection: TypeError: Importing a module script failed. (anonymous function) (1ae26_@better-auth_core_dist_2ead24dc._.js:99) ``` This is running locally with node 22.17.0, next 16.0.4, @polar-sh/better-auth ^1.5.0, better-auth 1.4.2 and chrome 142.0.7444.176
Author
Owner

@batpool commented on GitHub (Nov 27, 2025):

I'm also getting this issue when using the polarClient plugin:

import { polarClient } from "@polar-sh/better-auth";
import { createAuthClient } from "better-auth/react";
export const authClient = createAuthClient({
baseURL: process.env.NEXT_PUBLIC_APP_URL,
plugins: [polarClient()],
});
When I comment out the polarClient lines, the error goes away.

I've attached my console logs below from the browser:

[Error] Failed to load resource: unsupported URL (node:async_hooks, line 0)
[Warning] [better-auth] Warning: AsyncLocalStorage is not available in this environment. Some features may not work as expected. (7ae12_next_dist_e6700ec0._.js, line 2288)
[Warning] [better-auth] Please read more about this warning at https://better-auth.com/docs/installation#mount-handler (7ae12_next_dist_e6700ec0._.js, line 2288)
[Warning] [better-auth] If you are using Cloudflare Workers, please see: https://developers.cloudflare.com/workers/configuration/compatibility-flags/#nodejs-compatibility-flag (7ae12_next_dist_e6700ec0._.js, line 2288)
[Error] Unhandled Promise Rejection: TypeError: Importing a module script failed.
	(anonymous function) (1ae26_@better-auth_core_dist_2ead24dc._.js:99)

This is running locally with node 22.17.0, next 16.0.4, @polar-sh/better-auth ^1.5.0, better-auth 1.4.2 and chrome 142.0.7444.176

i dont think this issue is noticed, we have to patch it manually, i have the patch but if its get fixed by the better auth team it will be good

<!-- gh-comment-id:3584400465 --> @batpool commented on GitHub (Nov 27, 2025): > I'm also getting this issue when using the polarClient plugin: > > import { polarClient } from "@polar-sh/better-auth"; > import { createAuthClient } from "better-auth/react"; > export const authClient = createAuthClient({ > baseURL: process.env.NEXT_PUBLIC_APP_URL, > plugins: [polarClient()], > }); > When I comment out the polarClient lines, the error goes away. > > I've attached my console logs below from the browser: > > ``` > [Error] Failed to load resource: unsupported URL (node:async_hooks, line 0) > [Warning] [better-auth] Warning: AsyncLocalStorage is not available in this environment. Some features may not work as expected. (7ae12_next_dist_e6700ec0._.js, line 2288) > [Warning] [better-auth] Please read more about this warning at https://better-auth.com/docs/installation#mount-handler (7ae12_next_dist_e6700ec0._.js, line 2288) > [Warning] [better-auth] If you are using Cloudflare Workers, please see: https://developers.cloudflare.com/workers/configuration/compatibility-flags/#nodejs-compatibility-flag (7ae12_next_dist_e6700ec0._.js, line 2288) > [Error] Unhandled Promise Rejection: TypeError: Importing a module script failed. > (anonymous function) (1ae26_@better-auth_core_dist_2ead24dc._.js:99) > ``` > > This is running locally with node 22.17.0, next 16.0.4, @polar-sh/better-auth ^1.5.0, better-auth 1.4.2 and chrome 142.0.7444.176 i dont think this issue is noticed, we have to patch it manually, i have the patch but if its get fixed by the better auth team it will be good
Author
Owner

@M4tT3d commented on GitHub (Nov 27, 2025):

I have the same problem on my next project with a custom plugin developed by me. I tried both nextjs 15 and 16 with app router but without solutions. The problem is related to the imports from better-auth/api. I'm using better-auth@1.4.3
Folder structure:

  • the server plugin is in src/lib/custom-auth/index.ts
  • the client plugin is in src/lib/custom-auth/client.ts
  • auth.ts is in the root of the project
  • there are two hooks in src/lib/custom-auth/hooks/
<!-- gh-comment-id:3585261161 --> @M4tT3d commented on GitHub (Nov 27, 2025): I have the same problem on my next project with a custom plugin developed by me. I tried both nextjs 15 and 16 with app router but without solutions. The problem is related to the imports from `better-auth/api`. I'm using better-auth@1.4.3 Folder structure: - the server plugin is in `src/lib/custom-auth/index.ts` - the client plugin is in `src/lib/custom-auth/client.ts` - `auth.ts` is in the root of the project - there are two hooks in `src/lib/custom-auth/hooks/`
Author
Owner

@fugisakimatheus commented on GitHub (Nov 27, 2025):

I'm having the same problem in my Next.js (v16) project, considering i only use the client because the back-end is in another project. The only places i use getSession are via the client, client.getSession() and this same error occurs:

  • I using better-auth@1.4.3
Failed to fetch dynamically imported module: node:async_hooks

See the browser errors print:
Image

I don't know if it could be related to something else as well.

Observation: Even after disabling the turbopack, the error persists.

<!-- gh-comment-id:3585889407 --> @fugisakimatheus commented on GitHub (Nov 27, 2025): I'm having the same problem in my Next.js (v16) project, considering i only use the client because the back-end is in another project. The only places i use getSession are via the client, `client.getSession()` and this same error occurs: - I using `better-auth@1.4.3` ``` Failed to fetch dynamically imported module: node:async_hooks ``` See the browser errors print: <img width="761" height="223" alt="Image" src="https://github.com/user-attachments/assets/5568100d-3bbd-4377-8046-f630d4ed0960" /> I don't know if it could be related to something else as well. _**Observation:** Even after disabling the `turbopack`, the error persists._
Author
Owner

@dennisjnnh commented on GitHub (Nov 27, 2025):

https://github.com/better-auth/better-auth/blob/canary/packages/core/src/async_hooks/index.ts

here its not checking for browser or not, it should be skipped in browser

i have the same issue where the browser tries to import node:async_hooks. updated to 1.4.3

<!-- gh-comment-id:3586216201 --> @dennisjnnh commented on GitHub (Nov 27, 2025): > https://github.com/better-auth/better-auth/blob/canary/packages/core/src/async_hooks/index.ts > > here its not checking for browser or not, it should be skipped in browser i have the same issue where the browser tries to import node:async_hooks. updated to 1.4.3
Author
Owner

@imqwertyc commented on GitHub (Nov 29, 2025):

I found a temporary solution for polarClient
use this plugin in your code as plugin:

import type { CheckoutParams, polar } from "@polar-sh/better-auth";
import { PolarEmbedCheckout } from "@polar-sh/checkout/embed";
import type { BetterAuthClientPlugin } from "better-auth";
import type { BetterFetchOption } from "better-auth/client";

export const polarClient = () => {
	return {
		id: "polar-client",
		$InferServerPlugin: {} as ReturnType<typeof polar>,
		getActions: ($fetch) => {
			return {
				checkoutEmbed: async (
					data: Omit<CheckoutParams, "redirect" | "embedOrigin">,
					fetchOptions?: BetterFetchOption,
				) => {
					const res = await $fetch("/checkout", {
						method: "POST",
						body: {
							...data,
							redirect: false,
							embedOrigin: window.location.origin,
						},
						...fetchOptions,
					});

					if (res.error) {
						throw new Error(res.error.message);
					}

					const checkout = res.data as { url: string };

					const theme =
						(new URL(checkout.url).searchParams.get("theme") as
							| "light"
							| "dark"
							| undefined) ?? "light";

					return await PolarEmbedCheckout.create(checkout.url, theme);
				},
			};
		},
	} satisfies BetterAuthClientPlugin;
};

this is the exact copy of polar's implementation and it works for me and the error disappears.
I don't know how this works, but it works.
Maybe polar has some problems with their imports.

<!-- gh-comment-id:3591589541 --> @imqwertyc commented on GitHub (Nov 29, 2025): I found a temporary solution for `polarClient` use this plugin in your code as plugin: ```ts import type { CheckoutParams, polar } from "@polar-sh/better-auth"; import { PolarEmbedCheckout } from "@polar-sh/checkout/embed"; import type { BetterAuthClientPlugin } from "better-auth"; import type { BetterFetchOption } from "better-auth/client"; export const polarClient = () => { return { id: "polar-client", $InferServerPlugin: {} as ReturnType<typeof polar>, getActions: ($fetch) => { return { checkoutEmbed: async ( data: Omit<CheckoutParams, "redirect" | "embedOrigin">, fetchOptions?: BetterFetchOption, ) => { const res = await $fetch("/checkout", { method: "POST", body: { ...data, redirect: false, embedOrigin: window.location.origin, }, ...fetchOptions, }); if (res.error) { throw new Error(res.error.message); } const checkout = res.data as { url: string }; const theme = (new URL(checkout.url).searchParams.get("theme") as | "light" | "dark" | undefined) ?? "light"; return await PolarEmbedCheckout.create(checkout.url, theme); }, }; }, } satisfies BetterAuthClientPlugin; }; ``` this is the exact copy of polar's implementation and it works for me and the error disappears. I don't know how this works, but it works. Maybe polar has some problems with their imports.
Author
Owner

@rust0258 commented on GitHub (Nov 29, 2025):

still the same issue with v1.4.3

Image
<!-- gh-comment-id:3591595411 --> @rust0258 commented on GitHub (Nov 29, 2025): still the same issue with v1.4.3 <img width="1598" height="512" alt="Image" src="https://github.com/user-attachments/assets/ade2c675-ae59-413f-84f6-9a02afd8bc9a" />
Author
Owner

@landoncolburn commented on GitHub (Nov 29, 2025):

I have a fix in the works, waiting on approvals

<!-- gh-comment-id:3591680225 --> @landoncolburn commented on GitHub (Nov 29, 2025): I have a fix in the works, waiting on approvals
Author
Owner

@nxtvoid commented on GitHub (Nov 29, 2025):

issue with polarClient()

https://github.com/polarsource/polar/issues/8166#issue-3677158290

<!-- gh-comment-id:3592035164 --> @nxtvoid commented on GitHub (Nov 29, 2025): issue with `polarClient()` https://github.com/polarsource/polar/issues/8166#issue-3677158290
Author
Owner

@pieterbeulque commented on GitHub (Dec 1, 2025):

Hey, Pieter from Polar checking in here.

From my debugging, what's happening is that our build starts to include a file that tries to import('node:async_hooks') when we use $InferServerPlugin: {} as ReturnType<typeof polarPlugin>.

node:async_hooks is only imported in Better Auth's test-utils file, so I don't really understand why this file would make it into a production build of the package. That's what I'm trying to figure out now so we can fix the issue in our client too.

I haven't found any other workaround yet, i.e. the $InferServerPlugin has to bridge from server-side code to client-side code, but in type-only world, so it should be doable.

<!-- gh-comment-id:3595351977 --> @pieterbeulque commented on GitHub (Dec 1, 2025): Hey, Pieter from Polar checking in here. From my debugging, what's happening is that our build starts to include a file that tries to `import('node:async_hooks')` when we use `$InferServerPlugin: {} as ReturnType<typeof polarPlugin>`. `node:async_hooks` is only imported in Better Auth's `test-utils` file, so I don't really understand why this file would make it into a production build of the package. That's what I'm trying to figure out now so we can fix the issue in our client too. I haven't found any other workaround yet, i.e. the `$InferServerPlugin` _has_ to bridge from server-side code to client-side code, but in type-only world, so it should be doable.
Author
Owner

@naodya commented on GitHub (Dec 3, 2025):

I also created this issue with some details and a workaround that worked for me:

import { PolarEmbedCheckout } from "@polar-sh/checkout/embed";

export const polarClient = () => ({
  id: "polar-client",
  $InferServerPlugin: {},
  getActions: ($fetch) => ({
    checkoutEmbed: async (data) => {
      const res = await $fetch("/checkout", {
        method: "POST",
        body: { ...data, redirect: false, embedOrigin: window.location.origin },
      });
      if (res.error) throw new Error(res.error.message);
      const theme = new URL(res.data.url).searchParams.get("theme") ?? "light";
      return await PolarEmbedCheckout.create(res.data.url, theme);
    },
  }),
});
<!-- gh-comment-id:3604590740 --> @naodya commented on GitHub (Dec 3, 2025): I also created [this issue](https://github.com/polarsource/polar/issues/8251) with some details and a workaround that worked for me: ```TypeScript import { PolarEmbedCheckout } from "@polar-sh/checkout/embed"; export const polarClient = () => ({ id: "polar-client", $InferServerPlugin: {}, getActions: ($fetch) => ({ checkoutEmbed: async (data) => { const res = await $fetch("/checkout", { method: "POST", body: { ...data, redirect: false, embedOrigin: window.location.origin }, }); if (res.error) throw new Error(res.error.message); const theme = new URL(res.data.url).searchParams.get("theme") ?? "light"; return await PolarEmbedCheckout.create(res.data.url, theme); }, }), }); ```
Author
Owner

@ijmozn commented on GitHub (Dec 5, 2025):

@landoncolburn @Bekacru
I update to tag 1.4.6-beta.3 which has the merged PR, I end up with Next JS (16.0.7 Turbopack) build error:
Code generation for chunk item errored, I reverted back to 1.4.5 but still node:async_hooks issue

⨯ ./node_modules/better-auth/dist/chunk-DieNfLhd.mjs
An error occurred while generating the chunk item [project]/node_modules/better-auth/dist/chunk-DieNfLhd.mjs [app-client] (ecmascript)

Caused by:

  • the chunking context (unknown) does not support external modules (request: node:module)

Debug info:

  • An error occurred while generating the chunk item [project]/node_modules/better-auth/dist/chunk-DieNfLhd.mjs [app-client] (ecmascript)
  • Execution of ::content_with_async_module_info failed
  • Execution of *EcmascriptChunkItemContent::new failed
  • Execution of EcmascriptModuleContent::new failed
  • the chunking context (unknown) does not support external modules (request: node:module)

Import traces:
Client Component Browser:
./node_modules/better-auth/dist/chunk-DieNfLhd.mjs [Client Component Browser]
./node_modules/better-auth/dist/get-migration--xV8I5XU.mjs [Client Component Browser]
./node_modules/better-auth/dist/api/index.mjs [Client Component Browser]
./node_modules/better-auth-credentials-plugin/dist/src/credentials/index.js [Client Component Browser]
./node_modules/better-auth-credentials-plugin/dist/index.js [Client Component Browser]
./src/lib/auth-client.ts [Client Component Browser]
./src/app/auth/actions.ts [Client Component Browser]
./src/components/auth/signin-form.tsx [Client Component Browser]
./src/app/auth/sign-in/page.tsx [Client Component Browser]
./src/app/auth/sign-in/page.tsx [Server Component]

Client Component SSR:
./node_modules/better-auth/dist/chunk-DieNfLhd.mjs [Client Component SSR]
./node_modules/better-auth/dist/get-migration--xV8I5XU.mjs [Client Component SSR]
./node_modules/better-auth/dist/api/index.mjs [Client Component SSR]
./node_modules/better-auth-credentials-plugin/dist/src/credentials/index.js [Client Component SSR]
./node_modules/better-auth-credentials-plugin/dist/index.js [Client Component SSR]
./src/lib/auth-client.ts [Client Component SSR]
./src/app/auth/actions.ts [Client Component SSR]
./src/components/auth/signin-form.tsx [Client Component SSR]
./src/app/auth/sign-in/page.tsx [Client Component SSR]
./src/app/auth/sign-in/page.tsx [Server Component]

<!-- gh-comment-id:3616529487 --> @ijmozn commented on GitHub (Dec 5, 2025): @landoncolburn @Bekacru I update to tag `1.4.6-beta.3` which has the merged PR, I end up with Next JS (16.0.7 Turbopack) build error: `Code generation for chunk item errored`, I reverted back to 1.4.5 but still `node:async_hooks` issue > > ⨯ ./node_modules/better-auth/dist/chunk-DieNfLhd.mjs > An error occurred while generating the chunk item [project]/node_modules/better-auth/dist/chunk-DieNfLhd.mjs [app-client] (ecmascript) > > Caused by: > - the chunking context (unknown) does not support external modules (request: node:module) > > Debug info: > - An error occurred while generating the chunk item [project]/node_modules/better-auth/dist/chunk-DieNfLhd.mjs [app-client] (ecmascript) > - Execution of <ModuleChunkItem as EcmascriptChunkItem>::content_with_async_module_info failed > - Execution of *EcmascriptChunkItemContent::new failed > - Execution of EcmascriptModuleContent::new failed > - the chunking context (unknown) does not support external modules (request: node:module) > > Import traces: > Client Component Browser: > ./node_modules/better-auth/dist/chunk-DieNfLhd.mjs [Client Component Browser] > ./node_modules/better-auth/dist/get-migration--xV8I5XU.mjs [Client Component Browser] > ./node_modules/better-auth/dist/api/index.mjs [Client Component Browser] > ./node_modules/better-auth-credentials-plugin/dist/src/credentials/index.js [Client Component Browser] > ./node_modules/better-auth-credentials-plugin/dist/index.js [Client Component Browser] > ./src/lib/auth-client.ts [Client Component Browser] > ./src/app/auth/actions.ts [Client Component Browser] > ./src/components/auth/signin-form.tsx [Client Component Browser] > ./src/app/auth/sign-in/page.tsx [Client Component Browser] > ./src/app/auth/sign-in/page.tsx [Server Component] > > Client Component SSR: > ./node_modules/better-auth/dist/chunk-DieNfLhd.mjs [Client Component SSR] > ./node_modules/better-auth/dist/get-migration--xV8I5XU.mjs [Client Component SSR] > ./node_modules/better-auth/dist/api/index.mjs [Client Component SSR] > ./node_modules/better-auth-credentials-plugin/dist/src/credentials/index.js [Client Component SSR] > ./node_modules/better-auth-credentials-plugin/dist/index.js [Client Component SSR] > ./src/lib/auth-client.ts [Client Component SSR] > ./src/app/auth/actions.ts [Client Component SSR] > ./src/components/auth/signin-form.tsx [Client Component SSR] > ./src/app/auth/sign-in/page.tsx [Client Component SSR] > ./src/app/auth/sign-in/page.tsx [Server Component] >
Author
Owner

@landoncolburn commented on GitHub (Dec 5, 2025):

I will try and reproduce this later, but at first glance it looks unrelated. Another issue from the co-bundling of client/server bundles though.

<!-- gh-comment-id:3616755243 --> @landoncolburn commented on GitHub (Dec 5, 2025): I will try and reproduce this later, but at first glance it looks unrelated. Another issue from the co-bundling of client/server bundles though.
Author
Owner

@landoncolburn commented on GitHub (Dec 5, 2025):

@ibrahimjel I was not able to reproduce this with the following configuration:

// package.json
// ...
"dependencies": {
	"better-auth": "1.4.6-beta.3",
	"next": "16.0.7",
	"react": "19.2.1",
	"react-dom": "19.2.1"
},
// ...
// auth.ts
import { betterAuth } from "better-auth";

export const auth = betterAuth({
	emailAndPassword: {
		enabled: true,
	},
});
// auth-client.ts
import { createAuthClient } from "better-auth/react";

export const authClient = createAuthClient({
	baseURL: "http://localhost:3000",
});

Output from next build:

> next build

   ▲ Next.js 16.0.6 (Turbopack)
   - Environments: .env.local

   Creating an optimized production build ...
 ✓ Compiled successfully in 1393.6ms
 ✓ Finished TypeScript in 1681.9ms    
 ✓ Collecting page data using 11 workers in 248.4ms    
 ✓ Generating static pages using 11 workers (4/4) in 270.0ms
 ✓ Finalizing page optimization in 8.0ms    

Route (app)
┌ ○ /
├ ○ /_not-found
└ ƒ /api/auth/[...all]


○  (Static)   prerendered as static content
ƒ  (Dynamic)  server-rendered on demand

If you're still encountering this issue please provide me with a reproducible example, and maybe open a new issue? Thank you!

<!-- gh-comment-id:3616960373 --> @landoncolburn commented on GitHub (Dec 5, 2025): @ibrahimjel I was not able to reproduce this with the following configuration: ```jsonc // package.json // ... "dependencies": { "better-auth": "1.4.6-beta.3", "next": "16.0.7", "react": "19.2.1", "react-dom": "19.2.1" }, // ... ``` ```ts // auth.ts import { betterAuth } from "better-auth"; export const auth = betterAuth({ emailAndPassword: { enabled: true, }, }); ``` ```ts // auth-client.ts import { createAuthClient } from "better-auth/react"; export const authClient = createAuthClient({ baseURL: "http://localhost:3000", }); ``` Output from `next build`: ``` > next build ▲ Next.js 16.0.6 (Turbopack) - Environments: .env.local Creating an optimized production build ... ✓ Compiled successfully in 1393.6ms ✓ Finished TypeScript in 1681.9ms ✓ Collecting page data using 11 workers in 248.4ms ✓ Generating static pages using 11 workers (4/4) in 270.0ms ✓ Finalizing page optimization in 8.0ms Route (app) ┌ ○ / ├ ○ /_not-found └ ƒ /api/auth/[...all] ○ (Static) prerendered as static content ƒ (Dynamic) server-rendered on demand ``` If you're still encountering this issue please provide me with a reproducible example, and maybe open a new issue? Thank you!
Author
Owner

@Re4GD commented on GitHub (Dec 5, 2025):

@landoncolburn twoFactorClient() is causing the issue for me


Edit: just realized, I was importing from better-auth/plugins, not better-auth/client/plugins

import {
  adminClient,
  inferAdditionalFields,
  lastLoginMethodClient,
  usernameClient,
} from "better-auth/client/plugins";
import { twoFactorClient } from "better-auth/plugins";
import { createAuthClient } from "better-auth/react";

When I moved the import to the top it went away. Why is better-auth/plugins exporting client plugins anyway?

<!-- gh-comment-id:3617140123 --> @Re4GD commented on GitHub (Dec 5, 2025): @landoncolburn twoFactorClient() is causing the issue for me --- Edit: just realized, I was importing from `better-auth/plugins`, not `better-auth/client/plugins` ```ts import { adminClient, inferAdditionalFields, lastLoginMethodClient, usernameClient, } from "better-auth/client/plugins"; import { twoFactorClient } from "better-auth/plugins"; import { createAuthClient } from "better-auth/react"; ``` When I moved the import to the top it went away. Why is `better-auth/plugins` exporting client plugins anyway?
Author
Owner

@landoncolburn commented on GitHub (Dec 5, 2025):

@Re4GD Good catch, for some reason the twoFactor plugin is re-exporting all of its client functions.

The line in question is here 9de80b35d8/packages/better-auth/src/plugins/two-factor/index.ts (L118)

These two tests will need to be updated as well:

938c2a7c31/packages/better-auth/src/plugins/two-factor/two-factor.test.ts (L9)

57ee11a26f/packages/better-auth/src/plugins/additional-fields/additional-fields.test.ts (L5)

I can make the change to remove the export, but it will be a breaking change if anyone is already using the incorrect path (as the two test cases were).

@Bekacru are you able to give any insight into why the client functions are being exported in this file?

This discussion should really be moved to a new issue though, as it's unrelated to async_hooks.

<!-- gh-comment-id:3617351247 --> @landoncolburn commented on GitHub (Dec 5, 2025): @Re4GD Good catch, for some reason the twoFactor plugin is re-exporting all of its client functions. The line in question is here https://github.com/better-auth/better-auth/blob/9de80b35d8ff4aac88173450231279d2d7e62048/packages/better-auth/src/plugins/two-factor/index.ts#L118 These two tests will need to be updated as well: https://github.com/better-auth/better-auth/blob/938c2a7c31fe6373fe63bce7368b0de725d911d8/packages/better-auth/src/plugins/two-factor/two-factor.test.ts#L9 https://github.com/better-auth/better-auth/blob/57ee11a26fd0d23d5504ba0c6e41631a4fa895f5/packages/better-auth/src/plugins/additional-fields/additional-fields.test.ts#L5 I can make the change to remove the export, but it will be a breaking change if anyone is already using the incorrect path (as the two test cases were). @Bekacru are you able to give any insight into why the client functions are being exported in this file? This discussion should really be moved to a new issue though, as it's unrelated to async_hooks.
Author
Owner

@mvriu5 commented on GitHub (Dec 6, 2025):

@ibrahimjel using a util method was the problem for me.
I changed the import from
import {capitalizeFirstLetter} from "@better-auth"
to
import {capitalizeFirstLetter} from "@better-auth/core/utils"

<!-- gh-comment-id:3619979792 --> @mvriu5 commented on GitHub (Dec 6, 2025): @ibrahimjel using a util method was the problem for me. I changed the import from `import {capitalizeFirstLetter} from "@better-auth"` to `import {capitalizeFirstLetter} from "@better-auth/core/utils"`
Author
Owner

@0-Sandy commented on GitHub (Dec 7, 2025):

I had the same error with my own plugin. In my case, the issue was that I was re-exporting the client from the plugin’s index.ts:

export { clientPlugin } from "./client";

And then importing it like this:

import { clientPlugin } from "./plugin";

The fix was to import the client directly from its actual file, without going through the re-export:

import { clientPlugin } from "./plugin/client";

I'm not sure if the Polar issue is fixed, but it's probably the same root cause. You just need to find where the client is defined and import it directly instead of relying on a re-export.

<!-- gh-comment-id:3623048689 --> @0-Sandy commented on GitHub (Dec 7, 2025): I had the same error with my own plugin. In my case, the issue was that I was **re-exporting the client from the plugin’s `index.ts`**: ```ts export { clientPlugin } from "./client"; ``` And then importing it like this: ```ts import { clientPlugin } from "./plugin"; ``` The fix was to **import the client directly from its actual file**, without going through the re-export: ```ts import { clientPlugin } from "./plugin/client"; ``` I'm not sure if the Polar issue is fixed, but it's probably the same root cause. You just need to find where the client is defined and import it directly instead of relying on a re-export.
Author
Owner

@troygoode commented on GitHub (Dec 8, 2025):

You guys were able to put me on the right track as well. I was exporting a server plug and client plugin from the same field; splitting it fixed this issue for me. My original file was this:

import { organizationClient as organizationClientPlugin } from "better-auth/client/plugins";
import { organization as organizationPlugin } from "better-auth/plugins";

export function organization() {
  return organizationPlugin({
    allowUserToCreateOrganization: async (_user) => {
      return true;
    },
  });
}

export function organizationClient() {
  return organizationClientPlugin({
    //
  });
}

I split it into 2 files:

// server plugin

import { organization as organizationPlugin } from "better-auth/plugins";

export function organization() {
  return organizationPlugin({
    allowUserToCreateOrganization: async (_user) => {
      return true;
    },
  });
}
// client plugin

import { organizationClient as organizationClientPlugin } from "better-auth/client/plugins";

export function organizationClient() {
  return organizationClientPlugin({
    //
  });
}
<!-- gh-comment-id:3629442455 --> @troygoode commented on GitHub (Dec 8, 2025): You guys were able to put me on the right track as well. I was exporting a server plug and client plugin from the same field; splitting it fixed this issue for me. My original file was this: ```typescript import { organizationClient as organizationClientPlugin } from "better-auth/client/plugins"; import { organization as organizationPlugin } from "better-auth/plugins"; export function organization() { return organizationPlugin({ allowUserToCreateOrganization: async (_user) => { return true; }, }); } export function organizationClient() { return organizationClientPlugin({ // }); } ``` I split it into 2 files: ```typescript // server plugin import { organization as organizationPlugin } from "better-auth/plugins"; export function organization() { return organizationPlugin({ allowUserToCreateOrganization: async (_user) => { return true; }, }); } ``` ```typescript // client plugin import { organizationClient as organizationClientPlugin } from "better-auth/client/plugins"; export function organizationClient() { return organizationClientPlugin({ // }); } ```
Author
Owner

@dennisjnnh commented on GitHub (Dec 9, 2025):

@landoncolburn twoFactorClient() is causing the issue for me

Edit: just realized, I was importing from better-auth/plugins, not better-auth/client/plugins

import {
adminClient,
inferAdditionalFields,
lastLoginMethodClient,
usernameClient,
} from "better-auth/client/plugins";
import { twoFactorClient } from "better-auth/plugins";
import { createAuthClient } from "better-auth/react";
When I moved the import to the top it went away. Why is better-auth/plugins exporting client plugins anyway?

This was the fix for async_hooks import on the client in my case.

<!-- gh-comment-id:3630925791 --> @dennisjnnh commented on GitHub (Dec 9, 2025): > [@landoncolburn](https://github.com/landoncolburn) twoFactorClient() is causing the issue for me > > Edit: just realized, I was importing from `better-auth/plugins`, not `better-auth/client/plugins` > > import { > adminClient, > inferAdditionalFields, > lastLoginMethodClient, > usernameClient, > } from "better-auth/client/plugins"; > import { twoFactorClient } from "better-auth/plugins"; > import { createAuthClient } from "better-auth/react"; > When I moved the import to the top it went away. Why is `better-auth/plugins` exporting client plugins anyway? This was the fix for async_hooks import on the client in my case.
Author
Owner

@CleverSource commented on GitHub (Dec 11, 2025):

@landoncolburn I am experiencing this same problem with the bundler. Using the admin plugin with this recommended setup.

If you try to import:

import { createAccessControl } from "better-auth/plugins";
import { adminAc, defaultStatements } from "better-auth/plugins/admin/access";

and then import the file using those imports (e.g. your permissions.ts file) into the client for type-safety:

export const authClient = createAuthClient({
  baseURL: `${getBaseUrl()}/api/auth`,
  plugins: [
    adminClient({
      ac,
      roles: {
        admin,
      },
    }),
  ],
});

Bundler issues will occur. Is there a way to fix this without losing type-safety?

<!-- gh-comment-id:3640292312 --> @CleverSource commented on GitHub (Dec 11, 2025): @landoncolburn I am experiencing this same problem with the bundler. Using the admin plugin with this recommended [setup](https://www.better-auth.com/docs/plugins/admin#access-control). If you try to import: ```ts import { createAccessControl } from "better-auth/plugins"; import { adminAc, defaultStatements } from "better-auth/plugins/admin/access"; ``` and then import the file using those imports (e.g. your `permissions.ts` file) into the client for type-safety: ```ts export const authClient = createAuthClient({ baseURL: `${getBaseUrl()}/api/auth`, plugins: [ adminClient({ ac, roles: { admin, }, }), ], }); ``` Bundler issues will occur. Is there a way to fix this without losing type-safety?
Author
Owner

@0-Sandy commented on GitHub (Dec 11, 2025):

@landoncolburn I am experiencing this same problem with the bundler. Using the admin plugin with this recommended setup.

If you try to import:

import { createAccessControl } from "better-auth/plugins";
import { adminAc, defaultStatements } from "better-auth/plugins/admin/access";

and then import the file using those imports (e.g. your permissions.ts file) into the client for type-safety:

export const authClient = createAuthClient({
  baseURL: `${getBaseUrl()}/api/auth`,
  plugins: [
    adminClient({
      ac,
      roles: {
        admin,
      },
    }),
  ],
});

Bundler issues will occur. Is there a way to fix this without losing type-safety?

It looks like the issue comes from importing createAccessControl from the wrong module.
In your code you have:

import { createAccessControl } from "better-auth/plugins";

However, according to the Better Auth docs, it should be imported from the access plugin:

import { createAccessControl } from "better-auth/plugins/access";

Docs reference: https://www.better-auth.com/docs/plugins/admin#create-access-control

<!-- gh-comment-id:3641947204 --> @0-Sandy commented on GitHub (Dec 11, 2025): > @landoncolburn I am experiencing this same problem with the bundler. Using the admin plugin with this recommended [setup](https://www.better-auth.com/docs/plugins/admin#access-control). > > If you try to import: > ```ts > import { createAccessControl } from "better-auth/plugins"; > import { adminAc, defaultStatements } from "better-auth/plugins/admin/access"; > ``` > > and then import the file using those imports (e.g. your `permissions.ts` file) into the client for type-safety: > ```ts > export const authClient = createAuthClient({ > baseURL: `${getBaseUrl()}/api/auth`, > plugins: [ > adminClient({ > ac, > roles: { > admin, > }, > }), > ], > }); > ``` > > Bundler issues will occur. Is there a way to fix this without losing type-safety? It looks like the issue comes from importing `createAccessControl` from the wrong module. In your code you have: ```ts import { createAccessControl } from "better-auth/plugins"; ``` However, according to the Better Auth docs, it should be imported from the **access plugin**: ```ts import { createAccessControl } from "better-auth/plugins/access"; ``` Docs reference: https://www.better-auth.com/docs/plugins/admin#create-access-control
Author
Owner

@CleverSource commented on GitHub (Dec 11, 2025):

@landoncolburn I am experiencing this same problem with the bundler. Using the admin plugin with this recommended setup.

If you try to import:

import { createAccessControl } from "better-auth/plugins";
import { adminAc, defaultStatements } from "better-auth/plugins/admin/access";

and then import the file using those imports (e.g. your permissions.ts file) into the client for type-safety:

export const authClient = createAuthClient({
  baseURL: `${getBaseUrl()}/api/auth`,
  plugins: [
    adminClient({
      ac,
      roles: {
        admin,
      },
    }),
  ],
});

Bundler issues will occur. Is there a way to fix this without losing type-safety?

It looks like the issue comes from importing createAccessControl from the wrong module.
In your code you have:

import { createAccessControl } from "better-auth/plugins";

However, according to the Better Auth docs, it should be imported from the access plugin:

import { createAccessControl } from "better-auth/plugins/access";

Docs reference: https://www.better-auth.com/docs/plugins/admin#create-access-control

This fixed it! Thanks for pointing that out

<!-- gh-comment-id:3642601562 --> @CleverSource commented on GitHub (Dec 11, 2025): > > @landoncolburn I am experiencing this same problem with the bundler. Using the admin plugin with this recommended [setup](https://www.better-auth.com/docs/plugins/admin#access-control). > > > > If you try to import: > > ```ts > > import { createAccessControl } from "better-auth/plugins"; > > import { adminAc, defaultStatements } from "better-auth/plugins/admin/access"; > > ``` > > > > and then import the file using those imports (e.g. your `permissions.ts` file) into the client for type-safety: > > ```ts > > export const authClient = createAuthClient({ > > baseURL: `${getBaseUrl()}/api/auth`, > > plugins: [ > > adminClient({ > > ac, > > roles: { > > admin, > > }, > > }), > > ], > > }); > > ``` > > > > Bundler issues will occur. Is there a way to fix this without losing type-safety? > > It looks like the issue comes from importing `createAccessControl` from the wrong module. > In your code you have: > > ```ts > import { createAccessControl } from "better-auth/plugins"; > ``` > > However, according to the Better Auth docs, it should be imported from the **access plugin**: > > ```ts > import { createAccessControl } from "better-auth/plugins/access"; > ``` > > Docs reference: https://www.better-auth.com/docs/plugins/admin#create-access-control This fixed it! Thanks for pointing that out
Author
Owner

@aleksa-codes commented on GitHub (Dec 12, 2025):

I'm still seeing this in better-auth@1.4.1 in a standard Next.js App Router app (Next 15, Node 22, pnpm).

In my case it only happens when I add the Polar adapter client plugin:

import { createAuthClient } from "better-auth/react";
import { polarClient } from "@polar-sh/better-auth";

export const authClient = createAuthClient({
baseURL: process.env.NEXT_PUBLIC_API_URL || "http://localhost:4000",
plugins: [polarClient()],
});
As soon as this runs in the browser I get:

Failed to fetch dynamically imported module: node:async_hooks

If I remove polarClient() from the plugins array, the error disappears and everything works as expected. No Cloudflare / edge runtime involved here just a regular Node runtime with Express backend + Next.js frontend.

I’ve opened a related issue on the Polar adapters repo as well, and for now they suggested using the Polar SDK directly for embedded checkout as a workaround. That works for checkout, but it doesn’t cover the extra client methods shown in the Better Auth Polar docs (e.g. authClient.customer.orders.list, authClient.customer.benefits.list, etc.), which rely on the polarClient() plugin being usable on the frontend.

Edit: Yes client functions are working, only problem is console logs Failed to fetch dynamically imported module: node:async_hooks

@ibrahimjel
switching from:

import { polarClient } from "@polar-sh/better-auth";

to

import { polarClient } from "@polar-sh/better-auth/client"

Solved it for me. Both Polar and Better Auth docs still say to use "@polar-sh/better-auth" tho

<!-- gh-comment-id:3646695288 --> @aleksa-codes commented on GitHub (Dec 12, 2025): > I'm still seeing this in `better-auth@1.4.1` in a standard Next.js App Router app (Next 15, Node 22, pnpm). > > In my case it only happens when I add the Polar adapter client plugin: > > import { createAuthClient } from "better-auth/react"; > import { polarClient } from "@polar-sh/better-auth"; > > export const authClient = createAuthClient({ > baseURL: process.env.NEXT_PUBLIC_API_URL || "http://localhost:4000", > plugins: [polarClient()], > }); > As soon as this runs in the browser I get: > > > Failed to fetch dynamically imported module: node:async_hooks > > If I remove polarClient() from the plugins array, the error disappears and everything works as expected. No Cloudflare / edge runtime involved here just a regular Node runtime with Express backend + Next.js frontend. > > I’ve opened a related issue on the Polar adapters repo as well, and for now they suggested using the Polar SDK directly for embedded checkout as a workaround. That works for checkout, but it doesn’t cover the extra client methods shown in the Better Auth Polar docs (e.g. authClient.customer.orders.list, authClient.customer.benefits.list, etc.), which rely on the polarClient() plugin being usable on the frontend. > > Edit: Yes client functions are working, only problem is console logs Failed to fetch dynamically imported module: node:async_hooks @ibrahimjel switching from: ```ts import { polarClient } from "@polar-sh/better-auth"; ``` to ```ts import { polarClient } from "@polar-sh/better-auth/client" ``` Solved it for me. Both Polar and Better Auth docs still say to use `"@polar-sh/better-auth"` tho
Author
Owner

@thewh1teagle commented on GitHub (Dec 15, 2025):

Strangely when providing polarClient() from @polar-sh/better-auth/client to createAuthClient(...) it shows typescript errors.

Related

<!-- gh-comment-id:3657468783 --> @thewh1teagle commented on GitHub (Dec 15, 2025): Strangely when providing `polarClient()` from `@polar-sh/better-auth/client` to `createAuthClient(...)` it shows typescript errors. Related - https://github.com/polarsource/polar-adapters/issues/336 - https://github.com/polarsource/polar-adapters/issues/292
Author
Owner

@aleksa-codes commented on GitHub (Dec 16, 2025):

Strangely when providing polarClient() from @polar-sh/better-auth/client to createAuthClient(...) it shows typescript errors.

Related

Looks like it got solved in "better-auth": "^1.4.7" importing from "@polar-sh/better-auth" works as expected now and builds successfully,

<!-- gh-comment-id:3660030258 --> @aleksa-codes commented on GitHub (Dec 16, 2025): > Strangely when providing `polarClient()` from `@polar-sh/better-auth/client` to `createAuthClient(...)` it shows typescript errors. > > Related > > * [polarClient import breaks Next.js 16 Turbopack: node:async_hooks not available in browser polarsource/polar-adapters#336](https://github.com/polarsource/polar-adapters/issues/336) > * [Polar + Better Auth Causes inferred type errors polarsource/polar-adapters#292](https://github.com/polarsource/polar-adapters/issues/292) Looks like it got solved in `"better-auth": "^1.4.7"` importing from `"@polar-sh/better-auth"` works as expected now and builds successfully,
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#10278