[GH-ISSUE #4896] Possible Incorrect Documentation or Possible Bug With baseURL + BETTER_AUTH_URL Enforcement #18733

Closed
opened 2026-04-15 17:21:46 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @JeffreyLind3 on GitHub (Sep 25, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/4896

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

I have just set up a super basic Better Auth project (using email + password + email OTP methods) in Next.js, using Vercel for deployment, --experimental-https in the npm run dev command, and Prisma as the DB. Relevant env vars I have set are APP_ORIGIN and BETTER_AUTH_SECRET.

Current vs. Expected behavior

In the better-auth/packages/better-auth/src/types/options.ts file in the codebase, the comment below exists for baseURL:

/**
 * Base URL for the Better Auth. This is typically the
 * root URL where your application server is hosted.
 * If not explicitly set,
 * the system will check the following environment variable:
 *
 * process.env.BETTER_AUTH_URL
 *
 * If not set it will throw an error.
 */
baseURL?: string;

The core of this issue that I am encountering is with this behavior between baseURL and BETTER_AUTH_URL. The comment says that if baseURL is not explicitly set (it is not set in my codebase) AND if BETTER_AUTH_URL is not set (it is not set in my codebase), then it will throw an error.

However, in neither of my environments (development (local to my machine, npm run dev n' stuff like that) and production) does an error occur despite me fulfilling the conditions for this error to occur. This implies that either the documentation is incorrect, or there is a bug with the code.

While looking at some previous Issues, I see that there was a merged PR + closed Issue relating to fixing a bug where it did not enforce this doc, then I saw another Issue relating to the env var AUTH_URL where there was discussion of fixing this comment. Additionally, on the online docs, they seem to cohere to the case where an error should not be thrown if this case that I have occurs.

If my understanding of it being a code documentation issue is correct, then I will open a PR and fix it in options.ts. If not, then I am kind of lost ngl!

What version of Better Auth are you using?

1.3.17

System info

{
  "system": {
    "platform": "darwin",
    "arch": "arm64",
    "version": "Darwin Kernel Version 25.1.0: Fri Sep 19 19:12:09 PDT 2025; root:xnu-12377.40.77.505.1~4/RELEASE_ARM64_T6020",
    "release": "25.1.0",
    "cpuCount": 10,
    "cpuModel": "Apple M2 Pro",
    "totalMemory": "16.00 GB",
    "freeMemory": "0.15 GB"
  },
  "node": {
    "version": "v24.7.0",
    "env": "development"
  },
  "packageManager": {
    "name": "npm",
    "version": "11.6.0"
  },
  "frameworks": [
    {
      "name": "next",
      "version": "^15.5.4"
    },
    {
      "name": "react",
      "version": "^19.1.1"
    }
  ],
  "databases": [
    {
      "name": "@prisma/client",
      "version": "^6.16.2"
    }
  ],
  "betterAuth": {
    "version": "^1.3.17",
    "config": {
      "emailAndPassword": {
        "enabled": true,
        "requireEmailVerification": true
      },
      "trustedOrigins": [
        "https://localhost:3000"
      ],
      "plugins": [
        {
          "name": "email-otp",
          "config": {
            "id": "email-otp",
            "endpoints": {},
            "hooks": {
              "after": [
                {}
              ]
            },
            "$ERROR_CODES": {
              "OTP_EXPIRED": "otp expired",
              "INVALID_OTP": "Invalid OTP",
              "INVALID_EMAIL": "Invalid email",
              "USER_NOT_FOUND": "User not found",
              "TOO_MANY_ATTEMPTS": "Too many attempts"
            },
            "rateLimit": [
              {
                "window": 60,
                "max": 3
              },
              {
                "window": 60,
                "max": 3
              },
              {
                "window": 60,
                "max": 3
              },
              {
                "window": 60,
                "max": 3
              }
            ]
          }
        },
        {
          "name": "next-cookies",
          "config": {
            "id": "next-cookies",
            "hooks": {
              "after": [
                {}
              ]
            }
          }
        }
      ]
    }
  }
}

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

Documentation, Other

Auth config (if applicable)

export const auth = betterAuth({
  database: prismaAdapter(prisma, { provider: "postgresql" }),
  emailAndPassword: { enabled: true, requireEmailVerification: true },
  trustedOrigins: [getAppOrigin()],
  plugins: [
    emailOTP({
      overrideDefaultEmailVerification: true,
      storeOTP: "hashed",
      async sendVerificationOTP({ email, otp }) {
        const resend = new Resend(getResendApiKey());
        const from = getResendFrom();
        await resend.emails.send({
          from,
          to: [email],
          subject: "Verify Your Email",
          react: EmailOTPTemplate({ code: otp }),
        });
      },
    }),
    nextCookies(),
  ],
});

Additional context

No response

Originally created by @JeffreyLind3 on GitHub (Sep 25, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/4896 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce I have just set up a super basic Better Auth project (using email + password + email OTP methods) in Next.js, using Vercel for deployment, --experimental-https in the npm run dev command, and Prisma as the DB. Relevant env vars I have set are APP_ORIGIN and BETTER_AUTH_SECRET. ### Current vs. Expected behavior In the `better-auth/packages/better-auth/src/types/options.ts` file in the codebase, the comment below exists for baseURL: ```typescript /** * Base URL for the Better Auth. This is typically the * root URL where your application server is hosted. * If not explicitly set, * the system will check the following environment variable: * * process.env.BETTER_AUTH_URL * * If not set it will throw an error. */ baseURL?: string; ``` The core of this issue that I am encountering is with this behavior between baseURL and BETTER_AUTH_URL. The comment says that if baseURL is not explicitly set (it is not set in my codebase) AND if BETTER_AUTH_URL is not set (it is not set in my codebase), then it will throw an error. However, in neither of my environments (development (local to my machine, npm run dev n' stuff like that) and production) does an error occur despite me fulfilling the conditions for this error to occur. This implies that either the documentation is incorrect, or there is a bug with the code. While looking at some previous Issues, I see that there was a merged PR + closed Issue relating to fixing a bug where it did not enforce this doc, then I saw another Issue relating to the env var AUTH_URL where there was discussion of fixing this comment. Additionally, on the online docs, they seem to cohere to the case where an error **should not** be thrown if this case that I have occurs. If my understanding of it being a code documentation issue is correct, then I will open a PR and fix it in `options.ts`. If not, then I am kind of lost ngl! ### What version of Better Auth are you using? 1.3.17 ### System info ```bash { "system": { "platform": "darwin", "arch": "arm64", "version": "Darwin Kernel Version 25.1.0: Fri Sep 19 19:12:09 PDT 2025; root:xnu-12377.40.77.505.1~4/RELEASE_ARM64_T6020", "release": "25.1.0", "cpuCount": 10, "cpuModel": "Apple M2 Pro", "totalMemory": "16.00 GB", "freeMemory": "0.15 GB" }, "node": { "version": "v24.7.0", "env": "development" }, "packageManager": { "name": "npm", "version": "11.6.0" }, "frameworks": [ { "name": "next", "version": "^15.5.4" }, { "name": "react", "version": "^19.1.1" } ], "databases": [ { "name": "@prisma/client", "version": "^6.16.2" } ], "betterAuth": { "version": "^1.3.17", "config": { "emailAndPassword": { "enabled": true, "requireEmailVerification": true }, "trustedOrigins": [ "https://localhost:3000" ], "plugins": [ { "name": "email-otp", "config": { "id": "email-otp", "endpoints": {}, "hooks": { "after": [ {} ] }, "$ERROR_CODES": { "OTP_EXPIRED": "otp expired", "INVALID_OTP": "Invalid OTP", "INVALID_EMAIL": "Invalid email", "USER_NOT_FOUND": "User not found", "TOO_MANY_ATTEMPTS": "Too many attempts" }, "rateLimit": [ { "window": 60, "max": 3 }, { "window": 60, "max": 3 }, { "window": 60, "max": 3 }, { "window": 60, "max": 3 } ] } }, { "name": "next-cookies", "config": { "id": "next-cookies", "hooks": { "after": [ {} ] } } } ] } } } ``` ### Which area(s) are affected? (Select all that apply) Documentation, Other ### Auth config (if applicable) ```typescript export const auth = betterAuth({ database: prismaAdapter(prisma, { provider: "postgresql" }), emailAndPassword: { enabled: true, requireEmailVerification: true }, trustedOrigins: [getAppOrigin()], plugins: [ emailOTP({ overrideDefaultEmailVerification: true, storeOTP: "hashed", async sendVerificationOTP({ email, otp }) { const resend = new Resend(getResendApiKey()); const from = getResendFrom(); await resend.emails.send({ from, to: [email], subject: "Verify Your Email", react: EmailOTPTemplate({ code: otp }), }); }, }), nextCookies(), ], }); ``` ### Additional context _No response_
GiteaMirror added the lockedbug labels 2026-04-15 17:21:46 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Sep 25, 2025):

Hi @JeffreyLind3! I'm Dosu and I’m helping the better-auth team.

You're correct—this is a documentation issue, not a bug. The comment in options.ts is outdated: the code does not throw an error if both baseURL and BETTER_AUTH_URL are unset. Instead, it tries to derive the base URL from other sources (like request headers or the browser), and if all else fails, it falls back to a default such as '/api/auth' in the client. An error is only thrown at runtime if a request comes in and absolutely no base URL can be determined, which is rare and not part of the initial config or environment variable check. This behavior is confirmed by recent PRs and tests, which show no error is thrown in your scenario and a fallback is used instead (source, source).

Updating the comment in options.ts to clarify this fallback behavior would align the docs with the actual implementation. Your plan to open a PR to fix the comment is spot on.

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:3332181847 --> @dosubot[bot] commented on GitHub (Sep 25, 2025): <!-- Greeting --> Hi @JeffreyLind3! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> You're correct—this is a documentation issue, not a bug. The comment in `options.ts` is outdated: the code does **not** throw an error if both `baseURL` and `BETTER_AUTH_URL` are unset. Instead, it tries to derive the base URL from other sources (like request headers or the browser), and if all else fails, it falls back to a default such as `'/api/auth'` in the client. An error is only thrown at runtime if a request comes in and absolutely no base URL can be determined, which is rare and not part of the initial config or environment variable check. This behavior is confirmed by recent PRs and tests, which show no error is thrown in your scenario and a fallback is used instead ([source](https://github.com/better-auth/better-auth/pull/4760), [source](https://github.com/better-auth/better-auth/pull/4887)). Updating the comment in `options.ts` to clarify this fallback behavior would align the docs with the actual implementation. Your plan to open a PR to fix the comment is spot on. <!-- 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/dded6c62-5dc9-4966-8f57-6a8f7a269639?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/dded6c62-5dc9-4966-8f57-6a8f7a269639?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/dded6c62-5dc9-4966-8f57-6a8f7a269639?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/dded6c62-5dc9-4966-8f57-6a8f7a269639?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/dded6c62-5dc9-4966-8f57-6a8f7a269639?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/dded6c62-5dc9-4966-8f57-6a8f7a269639?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/dded6c62-5dc9-4966-8f57-6a8f7a269639?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/4896)
Author
Owner

@himself65 commented on GitHub (Sep 25, 2025):

Landed in cc656fb87d

<!-- gh-comment-id:3332682528 --> @himself65 commented on GitHub (Sep 25, 2025): Landed in https://github.com/better-auth/better-auth/commit/cc656fb87dbea1942f7c748f54ed1a7c5ac7a6d0
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#18733