[GH-ISSUE #3384] Some BetterAuth endpoints fail in Elysia #18215

Closed
opened 2026-04-15 16:36:17 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @cholasimmons on GitHub (Jul 15, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/3384

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  • any basic setup of Elysia and BetterAuth from the Elysia docs will do, or you can clone my GitHub repo here

  • if a fresh project, include the plugin by installing it bun add @elysiajs/static and including it in elysia .use(staticPlugin())

  • modify the variable prefix: '/public' to prefix: '/' and most BetterAuth endpoints will cease to be resolved

  • below is a default configuration:

.use(staticPlugin({
        prefix: '/public',
        assets: 'public',
        indexHTML: false
    }))

Current vs. Expected behavior

BetterAuth endpoints should work normally, instead response is NOT_FOUND.
Only routes that seem to work (that i checked) are signing up or in by email, and creating a new organization

What version of Better Auth are you using?

1.2.12

Provide environment information

OS: Windows 11
Database Server: Laragon / `bun prisma dev`
Browser: Yandex, Firefox, Chrome
REST Client: Yaak

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

Backend

Auth config (if applicable)

import { betterAuth } from "better-auth";
import { prismaAdapter } from "better-auth/adapters/prisma";
import { admin as adminPlugin, openAPI, organization, twoFactor } from "better-auth/plugins";
import { db } from "./database";
import consts from "~config/consts";

const authBasePath = '/auth';
export const auth = betterAuth({
    basePath: authBasePath,
    database: prismaAdapter(db, {
        provider: "postgresql", // or "mysql", "postgresql", ...etc
    }),
    emailAndPassword: {  
        enabled: true
    },
    session: {
        cookieCache: {
            enabled: true,
            maxAge: 60 * 60 * 24 * 7 // 7 days
        },
        storeSessionInDatabase: false
    },
    advanced: {
        useSecureCookies: true
    },
    hooks: {
        // before / after hooks
    },
    plugins: [
        openAPI(),
        twoFactor(),
        adminPlugin({
            defaultRole: 'user',
            adminRoles: 'admin'
        }),
        organization()
    ],
    appName: consts.server.name
});

let _schema: ReturnType<typeof auth.api.generateOpenAPISchema>
const getSchema = async () => (_schema ??= auth.api.generateOpenAPISchema())

export const OpenAPI = {
    getPaths: (prefix = authBasePath) =>
        getSchema().then(({ paths }) => {
            const reference: typeof paths = Object.create(null)

            for (const path of Object.keys(paths)) {
                const key = prefix + path
                reference[key] = paths[path]

                for (const method of Object.keys(paths[path])) {
                    const operation = (reference[key] as any)[method]

                    operation.tags = ['Better Auth']
                }
            }
            return reference
        }) as Promise<any>,
    components: getSchema().then(({ components }) => components) as Promise<any>
} as const

Additional context

No response

Originally created by @cholasimmons on GitHub (Jul 15, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/3384 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce - any basic setup of Elysia and BetterAuth from [the Elysia docs](https://elysiajs.com/integrations/better-auth.html) will do, or you can clone [my GitHub repo here](https://github.com/cholasimmons/furr-buddies_api_elysia) - if a fresh project, include the plugin by installing it `bun add @elysiajs/static` and including it in elysia `.use(staticPlugin())` - modify the variable `prefix: '/public'` to `prefix: '/'` and most BetterAuth endpoints will cease to be resolved - below is a default configuration: ```ts .use(staticPlugin({ prefix: '/public', assets: 'public', indexHTML: false })) ``` ### Current vs. Expected behavior BetterAuth endpoints should work normally, instead response is `NOT_FOUND`. Only routes that seem to work (that i checked) are signing up or in by email, and creating a new organization ### What version of Better Auth are you using? 1.2.12 ### Provide environment information ```bash OS: Windows 11 Database Server: Laragon / `bun prisma dev` Browser: Yandex, Firefox, Chrome REST Client: Yaak ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth"; import { prismaAdapter } from "better-auth/adapters/prisma"; import { admin as adminPlugin, openAPI, organization, twoFactor } from "better-auth/plugins"; import { db } from "./database"; import consts from "~config/consts"; const authBasePath = '/auth'; export const auth = betterAuth({ basePath: authBasePath, database: prismaAdapter(db, { provider: "postgresql", // or "mysql", "postgresql", ...etc }), emailAndPassword: { enabled: true }, session: { cookieCache: { enabled: true, maxAge: 60 * 60 * 24 * 7 // 7 days }, storeSessionInDatabase: false }, advanced: { useSecureCookies: true }, hooks: { // before / after hooks }, plugins: [ openAPI(), twoFactor(), adminPlugin({ defaultRole: 'user', adminRoles: 'admin' }), organization() ], appName: consts.server.name }); let _schema: ReturnType<typeof auth.api.generateOpenAPISchema> const getSchema = async () => (_schema ??= auth.api.generateOpenAPISchema()) export const OpenAPI = { getPaths: (prefix = authBasePath) => getSchema().then(({ paths }) => { const reference: typeof paths = Object.create(null) for (const path of Object.keys(paths)) { const key = prefix + path reference[key] = paths[path] for (const method of Object.keys(paths[path])) { const operation = (reference[key] as any)[method] operation.tags = ['Better Auth'] } } return reference }) as Promise<any>, components: getSchema().then(({ components }) => components) as Promise<any> } as const ``` ### Additional context _No response_
Author
Owner

@dosubot[bot] commented on GitHub (Jul 15, 2025):

This is a known issue with Elysia: when you set the staticPlugin prefix to '/', it takes precedence and overrides dynamic routes—including BetterAuth endpoints—causing them to return NOT_FOUND. This doesn't happen with a non-root prefix like '/public', which avoids route conflicts and allows BetterAuth endpoints to work as expected. This behavior is confirmed in related issues and discussions (example).

The best practice is to avoid using '/' as the staticPlugin prefix if you need dynamic API routes. Stick with a subpath like '/public', or ensure that your BetterAuth middleware is registered before the staticPlugin (though Elysia's plugin order and route matching may still cause issues if prefixes overlap).

If you need to serve static files from the root, consider using a custom middleware for BetterAuth endpoints, as shown in the integration docs and related issues:

const betterAuthMiddleware = new Elysia({ name: 'better-auth' })
  .all('/auth/*', (context) => {
    if (['POST', 'GET'].includes(context.request.method)) {
      return auth.handler(context.request);
    }
    context.status(405);
  });

const app = new Elysia()
  .use(betterAuthMiddleware)
  .use(staticPlugin({ prefix: '/', assets: 'public', indexHTML: false }));

This ensures BetterAuth endpoints are handled before static file serving. For more details, see the Elysia integration docs.

To reply, just mention @dosu.


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

<!-- gh-comment-id:3072444170 --> @dosubot[bot] commented on GitHub (Jul 15, 2025): <!-- Answer --> This is a known issue with Elysia: when you set the staticPlugin prefix to `'/'`, it takes precedence and overrides dynamic routes—including BetterAuth endpoints—causing them to return `NOT_FOUND`. This doesn't happen with a non-root prefix like `'/public'`, which avoids route conflicts and allows BetterAuth endpoints to work as expected. This behavior is confirmed in related issues and discussions ([example](https://github.com/better-auth/better-auth/issues/2959)). The best practice is to avoid using `'/'` as the staticPlugin prefix if you need dynamic API routes. Stick with a subpath like `'/public'`, or ensure that your BetterAuth middleware is registered before the staticPlugin (though Elysia's plugin order and route matching may still cause issues if prefixes overlap). If you need to serve static files from the root, consider using a custom middleware for BetterAuth endpoints, as shown in the [integration docs and related issues](https://github.com/better-auth/better-auth/issues/2959): ```typescript const betterAuthMiddleware = new Elysia({ name: 'better-auth' }) .all('/auth/*', (context) => { if (['POST', 'GET'].includes(context.request.method)) { return auth.handler(context.request); } context.status(405); }); const app = new Elysia() .use(betterAuthMiddleware) .use(staticPlugin({ prefix: '/', assets: 'public', indexHTML: false })); ``` This ensures BetterAuth endpoints are handled before static file serving. For more details, see the [Elysia integration docs](https://github.com/better-auth/better-auth/pull/213). <!-- 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/0ad052ad-d327-402c-bdd6-2716b5de1cd8?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/0ad052ad-d327-402c-bdd6-2716b5de1cd8?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/0ad052ad-d327-402c-bdd6-2716b5de1cd8?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/0ad052ad-d327-402c-bdd6-2716b5de1cd8?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/0ad052ad-d327-402c-bdd6-2716b5de1cd8?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/0ad052ad-d327-402c-bdd6-2716b5de1cd8?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/0ad052ad-d327-402c-bdd6-2716b5de1cd8?feedback_type=other)</sup>&nbsp;&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/3384)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#18215