[GH-ISSUE #8689] updateUser doesn't check if username is available #28485

Closed
opened 2026-04-17 19:56:09 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @rosano on GitHub (Mar 19, 2026).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/8689

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

Create User A with username "test".

Current vs. Expected behavior

isUsernameAvailable returns false as expected.

const { data, error } = await isUsernameAvailable({
  username: 'test',
});`
// data.available is false

User B can still set its username to "test":

updateUser({
   username: 'test',
});
// still sets the username

What version of Better Auth are you using?

1.5.3

System info

{
  "system": {
    "platform": "darwin",
    "arch": "x64",
    "version": "Darwin Kernel Version 21.6.0: Mon Jun 24 00:56:10 PDT 2024; root:xnu-8020.240.18.709.2~1/RELEASE_X86_64",
    "release": "21.6.0",
    "cpuCount": 8,
    "cpuModel": "Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz",
    "totalMemory": "16.00 GB",
    "freeMemory": "0.13 GB"
  },
  "node": {
    "version": "v22.22.0",
    "env": "development"
  },
  "packageManager": {
    "name": "npm",
    "version": "10.9.4"
  },
  "frameworks": [
    {
      "name": "svelte",
      "version": "^5.46.4"
    },
    {
      "name": "@sveltejs/kit",
      "version": "^2.49.5"
    }
  ],
  "databases": null,
  "betterAuth": {
    "version": "^1.5.3",
    "config": null
  }
}

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

Client

Auth config (if applicable)

import { betterAuth } from "better-auth"
export const auth = betterAuth({
  disablePaths: ['/is-username-available'],
  plugins: [
    username({
      displayUsernameNormalization: () => '',
    }),
  ],
});

Additional context

No response

Originally created by @rosano on GitHub (Mar 19, 2026). Original GitHub issue: https://github.com/better-auth/better-auth/issues/8689 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce Create User A with `username` "test". ### Current vs. Expected behavior `isUsernameAvailable` returns false as expected. ```javascript const { data, error } = await isUsernameAvailable({ username: 'test', });` // data.available is false ``` User B can still set its username to "test": ``` updateUser({ username: 'test', }); // still sets the username ``` ### What version of Better Auth are you using? 1.5.3 ### System info ```bash { "system": { "platform": "darwin", "arch": "x64", "version": "Darwin Kernel Version 21.6.0: Mon Jun 24 00:56:10 PDT 2024; root:xnu-8020.240.18.709.2~1/RELEASE_X86_64", "release": "21.6.0", "cpuCount": 8, "cpuModel": "Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz", "totalMemory": "16.00 GB", "freeMemory": "0.13 GB" }, "node": { "version": "v22.22.0", "env": "development" }, "packageManager": { "name": "npm", "version": "10.9.4" }, "frameworks": [ { "name": "svelte", "version": "^5.46.4" }, { "name": "@sveltejs/kit", "version": "^2.49.5" } ], "databases": null, "betterAuth": { "version": "^1.5.3", "config": null } } ``` ### Which area(s) are affected? (Select all that apply) Client ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" export const auth = betterAuth({ disablePaths: ['/is-username-available'], plugins: [ username({ displayUsernameNormalization: () => '', }), ], }); ``` ### Additional context _No response_
GiteaMirror added the lockedbug labels 2026-04-17 19:56:09 -05:00
Author
Owner

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

This is a confirmed bug. The username plugin's update-user middleware is supposed to validate username uniqueness but isn't working properly. Related issues have been reported in #2242 and #866.

Workaround: Until this is fixed, you can add a custom before hook to enforce validation:

hooks: {
  before: createAuthMiddleware(async (ctx) => {
    if (ctx.path !== '/update-user') return;
    if (ctx.body.username) {
      const existingUser = await ctx.context.adapter.findOne({
        model: 'user',
        where: [{ field: 'username', value: ctx.body.username }]
      });
      if (existingUser && existingUser.id !== ctx.context.session?.user.id) {
        throw new APIError('BAD_REQUEST', { message: 'Username already taken' });
      }
    }
  })
}

You can also enforce it at the database level by making the username column unique.

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

<!-- gh-comment-id:4090585982 --> @dosubot[bot] commented on GitHub (Mar 19, 2026): <!-- Answer --> This is a confirmed bug. The username plugin's [update-user middleware](https://github.com/better-auth/better-auth/blob/a0211a05a6b21cbec8b2639cc063f0d04dc3a690/packages/better-auth/src/plugins/username/index.ts#L486-L574) is supposed to validate username uniqueness but isn't working properly. Related issues have been reported in [#2242](https://github.com/better-auth/better-auth/issues/2242) and [#866](https://github.com/better-auth/better-auth/issues/866). **Workaround:** Until this is fixed, you can add a custom `before` hook to enforce validation: ```ts hooks: { before: createAuthMiddleware(async (ctx) => { if (ctx.path !== '/update-user') return; if (ctx.body.username) { const existingUser = await ctx.context.adapter.findOne({ model: 'user', where: [{ field: 'username', value: ctx.body.username }] }); if (existingUser && existingUser.id !== ctx.context.session?.user.id) { throw new APIError('BAD_REQUEST', { message: 'Username already taken' }); } } }) } ``` You can also enforce it at the database level by making the username column unique. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=brand-link).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/119b3f14-32d0-440b-9542-0150aea1cbcc?feedback_type=great_response&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/119b3f14-32d0-440b-9542-0150aea1cbcc?feedback_type=irrelevant_answer&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/119b3f14-32d0-440b-9542-0150aea1cbcc?feedback_type=incorrect_sources&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/119b3f14-32d0-440b-9542-0150aea1cbcc?feedback_type=too_verbose&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/119b3f14-32d0-440b-9542-0150aea1cbcc?feedback_type=hallucination&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/119b3f14-32d0-440b-9542-0150aea1cbcc?feedback_type=bug_report&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-bug_report) | [Other](https://app.dosu.dev/response-feedback/119b3f14-32d0-440b-9542-0150aea1cbcc?feedback_type=other&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-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&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=chat-badge)&nbsp;[![Open in Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=This%20is%20a%20confirmed%20bug.%20The%20username%20plugin%27s%20%5Bupdate-user%20middleware%5D%28https%3A//github.com/better-auth/better-auth/blob/a0211a05a6b21cbec8b2639cc063f0d04dc3a690/packages/better-auth/src/plugins/username/index.ts%23L486-L574%29%20is%20supposed%20to%20validate%20username%20uniqueness%20but%20isn%27t%20working%20properly.%20Related%20issues%20have%20been%20reported%20in%20%5B%232242%5D%28https%3A//github.com/better-auth/better-auth/issues/2242%29%20and%20%5B%23866%5D%28https%3A//github.com/better-auth/better-auth/issues/866%29.%0A%0A%2A%2AWorkaround%3A%2A%2A%20Until%20this%20is%20fixed%2C%20you%20can%20add%20a%20custom%20%60before%60%20hook%20to%20enforce%20validation%3A%0A%0A%60%60%60ts%0Ahooks%3A%20%7B%0A%20%20before%3A%20createAuthMiddleware%28async%20%28ctx%29%20%3D%3E%20%7B%0A%20%20%20%20if%20%28ctx.path%20%21%3D%3D%20%27/update-user%27%29%20return%3B%0A%20%20%20%20if%20%28ctx.body.username%29%20%7B%0A%20%20%20%20%20%20const%20existingUser%20%3D%20await%20ctx.context.adapter.findOne%28%7B%0A%20%20%20%20%20%20%20%20model%3A%20%27user%27%2C%0A%20%20%20%20%20%20%20%20where%3A%20%5B%7B%20field%3A%20%27username%27%2C%20value%3A%20ctx.body.username%20%7D%5D%0A%20%20%20%20%20%20%7D%29%3B%0A%20%20%20%20%20%20if%20%28existingUser%20%26%26%20existingUser.id%20%21%3D%3D%20ctx.context.session%3F.user.id%29%20%7B%0A%20%20%20%20%20%20%20%20throw%20new%20APIError%28%27BAD_REQUEST%27%2C%20%7B%20message%3A%20%27Username%20already%20taken%27%20%7D%29%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%7D%29%0A%7D%0A%60%60%60%0A%0AYou%20can%20also%20enforce%20it%20at%20the%20database%20level%20by%20making%20the%20username%20column%20unique.)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=join-discord)&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/8689)
Author
Owner

@github-actions[bot] commented on GitHub (Mar 31, 2026):

This issue has been locked as it was closed more than 7 days ago. If you're experiencing a similar problem or you have additional context, please open a new issue and reference this one.

<!-- gh-comment-id:4165909320 --> @github-actions[bot] commented on GitHub (Mar 31, 2026): This issue has been locked as it was closed more than 7 days ago. If you're experiencing a similar problem or you have additional context, please open a new issue and reference this one.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#28485