[GH-ISSUE #9049] better-auth issue: APIError missing from @better-auth/core/error export breaks Nitro/Rollup bundling #19891

Open
opened 2026-04-15 19:15:16 -05:00 by GiteaMirror · 0 comments
Owner

Originally created by @IshanArya on GitHub (Apr 9, 2026).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/9049

Is this suited for github?

  • Yes, this is suited for github

Reproduction

Use better-auth with TanStack Start + Nitro (bun preset). The build has three phases: client, SSR, and Nitro. The Nitro phase re-bundles the SSR output with Rollup. During this phase, Rollup statically analyzes imports and fails:

node_modules/.nitro/vite/services/ssr/assets/router-OEoT-WHW.js (10:26):
"APIError" is not exported by "node_modules/@better-auth/core/dist/error/index.mjs",
imported by "node_modules/.nitro/vite/services/ssr/assets/router-OEoT-WHW.js".

import { BetterAuthError, APIError, BASE_ERROR_CODES } from "@better-auth/core/error";
                          ^

Root cause

@better-auth/core/dist/error/index.mjs only exports two symbols:

export { BASE_ERROR_CODES, BetterAuthError };

APIError is not included in this file. However, better-auth's own internal code imports it from @better-auth/core/error:

import { BetterAuthError, APIError, BASE_ERROR_CODES } from "@better-auth/core/error";

The package.json exports map for @better-auth/core correctly points ./error to ./dist/error/index.mjs, but the compiled file is missing the APIError export.

This works at runtime (Node.js/Bun resolve it fine), but breaks any bundler (Rollup, etc.) that statically analyzes exports during a re-bundling step — which is exactly what Nitro does.

Steps to reproduce

  1. Create a TanStack Start project with Nitro (preset: 'bun')
  2. Install better-auth@1.6.1
  3. Configure better-auth and mount the auth handler route
  4. Run bun --bun vite build
  5. Client and SSR phases succeed; Nitro phase fails with the error above

Current vs. Expected behavior

Current: @better-auth/core/dist/error/index.mjs exports { BASE_ERROR_CODES, BetterAuthError }. APIError is missing. Bundlers that statically analyze this file fail because better-auth's own code imports APIError from this path.

Expected: @better-auth/core/dist/error/index.mjs should also export APIError, since better-auth's own internal modules depend on it from the @better-auth/core/error subpath.

Workaround

Tell Nitro/Rollup not to bundle better-auth:

// vite.config.ts
nitro({
  preset: 'bun',
  rollupConfig: {
    external: ['better-auth', /^@better-auth\//],
  },
})

This leaves better-auth as external imports resolved at runtime (where it works fine), but prevents tree-shaking.

What version of Better Auth are you using?

1.6.1

System info

OS: Linux
Runtime: Bun 1.3.11
Framework: TanStack Start 1.166.3
Server: Nitro 3.0.1-alpha.2
Bundler: Vite 7.3.1 / Rollup

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

Backend, Client, Types, Package

Auth config (if applicable)

import { betterAuth } from "better-auth"
export const auth = betterAuth({
  emailAndPassword: {  
    enabled: true
  },
});

Additional context

The @better-auth/core/package.json exports map is correct:

"./error": {
  "dev-source": "./src/error/index.ts",
  "types": "./dist/error/index.d.mts",
  "default": "./dist/error/index.mjs"
}

The issue is specifically in the build/compilation step that produces dist/error/index.mjsAPIError is defined elsewhere in the package (likely re-exported from better-call) but is not included in the error subpath's compiled output.

Related but different: #8729 (TypeScript type inference issue with APIError class inheritance). #2582 (user-facing APIError import from better-auth — was resolved by documenting better-auth/api import path). This issue is about better-auth's own internal code failing during bundling due to the missing export.

Originally created by @IshanArya on GitHub (Apr 9, 2026). Original GitHub issue: https://github.com/better-auth/better-auth/issues/9049 ### Is this suited for github? - [x] Yes, this is suited for github ### Reproduction Use better-auth with TanStack Start + Nitro (bun preset). The build has three phases: client, SSR, and Nitro. The Nitro phase re-bundles the SSR output with Rollup. During this phase, Rollup statically analyzes imports and fails: ``` node_modules/.nitro/vite/services/ssr/assets/router-OEoT-WHW.js (10:26): "APIError" is not exported by "node_modules/@better-auth/core/dist/error/index.mjs", imported by "node_modules/.nitro/vite/services/ssr/assets/router-OEoT-WHW.js". import { BetterAuthError, APIError, BASE_ERROR_CODES } from "@better-auth/core/error"; ^ ``` ### Root cause `@better-auth/core/dist/error/index.mjs` only exports two symbols: ```js export { BASE_ERROR_CODES, BetterAuthError }; ``` `APIError` is **not included** in this file. However, better-auth's own internal code imports it from `@better-auth/core/error`: ```js import { BetterAuthError, APIError, BASE_ERROR_CODES } from "@better-auth/core/error"; ``` The `package.json` exports map for `@better-auth/core` correctly points `./error` to `./dist/error/index.mjs`, but the compiled file is missing the `APIError` export. This works at runtime (Node.js/Bun resolve it fine), but breaks any bundler (Rollup, etc.) that statically analyzes exports during a re-bundling step — which is exactly what Nitro does. ### Steps to reproduce 1. Create a TanStack Start project with Nitro (`preset: 'bun'`) 2. Install `better-auth@1.6.1` 3. Configure better-auth and mount the auth handler route 4. Run `bun --bun vite build` 5. Client and SSR phases succeed; Nitro phase fails with the error above ### Current vs. Expected behavior **Current:** `@better-auth/core/dist/error/index.mjs` exports `{ BASE_ERROR_CODES, BetterAuthError }`. `APIError` is missing. Bundlers that statically analyze this file fail because better-auth's own code imports `APIError` from this path. **Expected:** `@better-auth/core/dist/error/index.mjs` should also export `APIError`, since better-auth's own internal modules depend on it from the `@better-auth/core/error` subpath. ## Workaround Tell Nitro/Rollup not to bundle better-auth: ```ts // vite.config.ts nitro({ preset: 'bun', rollupConfig: { external: ['better-auth', /^@better-auth\//], }, }) ``` This leaves better-auth as external imports resolved at runtime (where it works fine), but prevents tree-shaking. ### What version of Better Auth are you using? 1.6.1 ### System info ```bash OS: Linux Runtime: Bun 1.3.11 Framework: TanStack Start 1.166.3 Server: Nitro 3.0.1-alpha.2 Bundler: Vite 7.3.1 / Rollup ``` ### Which area(s) are affected? (Select all that apply) Backend, Client, Types, Package ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" export const auth = betterAuth({ emailAndPassword: { enabled: true }, }); ``` ### Additional context The `@better-auth/core/package.json` exports map is correct: ```json "./error": { "dev-source": "./src/error/index.ts", "types": "./dist/error/index.d.mts", "default": "./dist/error/index.mjs" } ``` The issue is specifically in the build/compilation step that produces `dist/error/index.mjs` — `APIError` is defined elsewhere in the package (likely re-exported from `better-call`) but is not included in the error subpath's compiled output. Related but different: #8729 (TypeScript type inference issue with `APIError` class inheritance). #2582 (user-facing `APIError` import from `better-auth` — was resolved by documenting `better-auth/api` import path). This issue is about better-auth's **own internal code** failing during bundling due to the missing export.
GiteaMirror added the core label 2026-04-15 19:15:16 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#19891