Expected an error object to be thrown on hooks. #3013

Closed
opened 2026-03-13 10:34:21 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @RSickenberg on GitHub (Mar 7, 2026).

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

Here is an example of hook i'm using.


  hooks: {
    before: createAuthMiddleware(async (ctx) => {
      if (ctx.path !== '/sign-up/email') {
        return
      }

      if (ctx.body?.acceptedTerms === null || !ctx.body?.acceptedTerms) {
        throw new APIError('BAD_REQUEST', {
          message: 'Terms and conditions must be accepted.',
        })
      }

      // Validate complexity of the password.
      const password: string = ctx.body?.password as string
      const complexityRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&\.\-\_])[A-Za-z\d@$!%*?&\.\_\-]{8,}$/
      if (!complexityRegex.test(password)) {
        throw new APIError('BAD_REQUEST', {
          message: 'This password must respect the rule.',
        })
      }
    }),
  },

Current vs. Expected behavior

ESLint 9.39.4 flags me the "throw new APIError" with @typescript-eslint/only-throw-error

What version of Better Auth are you using?

1.5.4

System info

{
  "system": {
    "platform": "darwin",
    "arch": "arm64",
    "version": "Darwin Kernel Version 25.3.0: Wed Jan 28 20:54:46 PST 2026; root:xnu-12377.91.3~2/RELEASE_ARM64_T6000",
    "release": "25.3.0",
    "cpuCount": 10,
    "cpuModel": "Apple M1 Max",
    "totalMemory": "32.00 GB",
    "freeMemory": "0.47 GB"
  },
  "node": {
    "version": "v24.14.0",
    "env": "development"
  },
  "packageManager": {
    "name": "npm",
    "version": "11.11.0"
  },
  "frameworks": [
    {
      "name": "next",
      "version": "^16.1.6"
    },
    {
      "name": "react",
      "version": "^19.2.4"
    }
  ],
  "databases": [
    {
      "name": "pg",
      "version": "^8.20.0"
    },
    {
      "name": "@prisma/client",
      "version": "^7.4.2"
    }
  ],
  "betterAuth": {
    "version": "Unknown",
    "config": null,
    "error": "Couldn't read your auth config. Make sure to default export your auth instance or to export as a variable named auth."
  }
}

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

Backend

Auth config (if applicable)


Additional context

No response

Originally created by @RSickenberg on GitHub (Mar 7, 2026). ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce Here is an example of hook i'm using. ```ts hooks: { before: createAuthMiddleware(async (ctx) => { if (ctx.path !== '/sign-up/email') { return } if (ctx.body?.acceptedTerms === null || !ctx.body?.acceptedTerms) { throw new APIError('BAD_REQUEST', { message: 'Terms and conditions must be accepted.', }) } // Validate complexity of the password. const password: string = ctx.body?.password as string const complexityRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&\.\-\_])[A-Za-z\d@$!%*?&\.\_\-]{8,}$/ if (!complexityRegex.test(password)) { throw new APIError('BAD_REQUEST', { message: 'This password must respect the rule.', }) } }), }, ``` ### Current vs. Expected behavior ESLint `9.39.4` flags me the "throw new APIError" with `@typescript-eslint/only-throw-error` ### What version of Better Auth are you using? 1.5.4 ### System info ```bash { "system": { "platform": "darwin", "arch": "arm64", "version": "Darwin Kernel Version 25.3.0: Wed Jan 28 20:54:46 PST 2026; root:xnu-12377.91.3~2/RELEASE_ARM64_T6000", "release": "25.3.0", "cpuCount": 10, "cpuModel": "Apple M1 Max", "totalMemory": "32.00 GB", "freeMemory": "0.47 GB" }, "node": { "version": "v24.14.0", "env": "development" }, "packageManager": { "name": "npm", "version": "11.11.0" }, "frameworks": [ { "name": "next", "version": "^16.1.6" }, { "name": "react", "version": "^19.2.4" } ], "databases": [ { "name": "pg", "version": "^8.20.0" }, { "name": "@prisma/client", "version": "^7.4.2" } ], "betterAuth": { "version": "Unknown", "config": null, "error": "Couldn't read your auth config. Make sure to default export your auth instance or to export as a variable named auth." } } ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript ``` ### Additional context _No response_
GiteaMirror added the bug label 2026-03-13 10:34:21 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Mar 7, 2026):

This ESLint warning happens because APIError extends BaseAPIError from the better-call/error package, rather than directly extending the native Error class. The @typescript-eslint/only-throw-error rule can't trace the inheritance chain through the external dependency.

Your code is correct—this is a false positive from ESLint's static analysis. You can suppress it per-line:

// eslint-disable-next-line @typescript-eslint/only-throw-error
throw new APIError('BAD_REQUEST', {
  message: 'Terms and conditions must be accepted.',
})

Or configure the rule in your ESLint config to allow throwing unknown types in those files.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other

Chat with Dosu Open in Cursor Join Discord Share on X

@dosubot[bot] commented on GitHub (Mar 7, 2026): <!-- Answer --> This ESLint warning happens because [`APIError` extends `BaseAPIError` from the `better-call/error` package](https://github.com/better-auth/better-auth/blob/7fefc2bbed2b66b2349ca182144b10eff171e345/packages/core/src/error/index.ts#L14-L35), rather than directly extending the native `Error` class. The `@typescript-eslint/only-throw-error` rule can't trace the inheritance chain through the external dependency. Your code is correct—this is a false positive from ESLint's static analysis. You can suppress it per-line: ```typescript // eslint-disable-next-line @typescript-eslint/only-throw-error throw new APIError('BAD_REQUEST', { message: 'Terms and conditions must be accepted.', }) ``` Or configure the rule in your ESLint config to allow throwing unknown types in those files. <!-- 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/deb405cf-c8b0-4d82-9c23-9a222c7b93ee?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/deb405cf-c8b0-4d82-9c23-9a222c7b93ee?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/deb405cf-c8b0-4d82-9c23-9a222c7b93ee?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/deb405cf-c8b0-4d82-9c23-9a222c7b93ee?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/deb405cf-c8b0-4d82-9c23-9a222c7b93ee?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/deb405cf-c8b0-4d82-9c23-9a222c7b93ee?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/deb405cf-c8b0-4d82-9c23-9a222c7b93ee?feedback_type=other)</sup> [![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Open in Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=This%20ESLint%20warning%20happens%20because%20%5B%60APIError%60%20extends%20%60BaseAPIError%60%20from%20the%20%60better-call/error%60%20package%5D%28https%3A//github.com/better-auth/better-auth/blob/7fefc2bbed2b66b2349ca182144b10eff171e345/packages/core/src/error/index.ts%23L14-L35%29%2C%20rather%20than%20directly%20extending%20the%20native%20%60Error%60%20class.%20The%20%60%40typescript-eslint/only-throw-error%60%20rule%20can%27t%20trace%20the%20inheritance%20chain%20through%20the%20external%20dependency.%0A%0AYour%20code%20is%20correct%E2%80%94this%20is%20a%20false%20positive%20from%20ESLint%27s%20static%20analysis.%20You%20can%20suppress%20it%20per-line%3A%0A%0A%60%60%60typescript%0A//%20eslint-disable-next-line%20%40typescript-eslint/only-throw-error%0Athrow%20new%20APIError%28%27BAD_REQUEST%27%2C%20%7B%0A%20%20message%3A%20%27Terms%20and%20conditions%20must%20be%20accepted.%27%2C%0A%7D%29%0A%60%60%60%0A%0AOr%20configure%20the%20rule%20in%20your%20ESLint%20config%20to%20allow%20throwing%20unknown%20types%20in%20those%20files.)&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/8472)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#3013