[GH-ISSUE #2242] minUsernameLength check is ignored when calling updateUser with an empty username #9111

Closed
opened 2026-04-13 04:27:03 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @brunocalou on GitHub (Apr 13, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/2242

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Setup the username plugin
plugins: [
	username({
		minUsernameLength: 3,
		maxUsernameLength: 20,
	}),
...
  1. Call authClient.updateUser with an empty username
authClient.updateUser({
	username: ''
});
  1. The username will be updated to an empty string

Current vs. Expected behavior

Current: the username is updated to an empty string
Expected: the username should fail to update and respect the minUsernameLength length

https://github.com/user-attachments/assets/10040298-6ff0-4c0b-b88b-dec98d9f1c1a

What version of Better Auth are you using?

^1.2.6

Provide environment information

- OS: Mac Os 15.3.1 (24D70)
- Browser: Brave Version 1.77.95 Chromium: 135.0.7049.52 (Official version)  (arm64)

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

Backend

Auth config (if applicable)

import { betterAuth } from 'better-auth';
import { drizzleAdapter } from 'better-auth/adapters/drizzle';
import { db } from './db/db';
import { admin, captcha, username } from 'better-auth/plugins';
import * as authSchema from './db/schema/auth';

export const auth = betterAuth({
	basePath: '/auth',
	trustedOrigins: [
		// ...
	],
	advanced: {
		crossSubDomainCookies: {
			enabled: true,
			domain: process.env.BETTER_AUTH_COOKIE_DOMAIN,
		},
		defaultCookieAttributes: {
			secure: true,
			httpOnly: true,
			sameSite: "none",  // Allows CORS-based cookie sharing across subdomains
			partitioned: true, // New browser standards will mandate this for foreign cookies
		},
		useSecureCookies: process.env.NODE_ENV === "production"
	},
	database: drizzleAdapter(db, {
		provider: 'pg',
		schema: authSchema,
	}),
	emailVerification: {
		sendVerificationEmail: async ({ user, url }) => {
			// ...
		},
		sendOnSignUp: true,
		expiresIn: 3600 // 1 hour
	},
	emailAndPassword: {
		enabled: true,
		requireEmailVerification: true,
		sendResetPassword: async ({ user, url }) => {
			// ...
		},
	},
	socialProviders: {
		google: {
			clientId: process.env.GOOGLE_CLIENT_ID as string,
			clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
		},
	},
	account: {
		accountLinking: {
			enabled: true,
			trustedProviders: ['google'],
		},
	},
	plugins: [
		username({
			minUsernameLength: 3,
			maxUsernameLength: 20,
		}),
		admin(),
		captcha({
			provider: 'cloudflare-turnstile', // or "google-recaptcha"
			secretKey: process.env.TURNSTILE_SECRET_KEY!,
		}),
	],
});

Additional context

I tested it on ^1.2.6 and ^1.2.5

Originally created by @brunocalou on GitHub (Apr 13, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/2242 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce 1. Setup the username plugin ```typescript plugins: [ username({ minUsernameLength: 3, maxUsernameLength: 20, }), ... ``` 2. Call `authClient.updateUser` with an empty username ```typescript authClient.updateUser({ username: '' }); ``` 3. The username will be updated to an empty string ### Current vs. Expected behavior Current: the username is updated to an empty string Expected: the username should fail to update and respect the `minUsernameLength` length https://github.com/user-attachments/assets/10040298-6ff0-4c0b-b88b-dec98d9f1c1a ### What version of Better Auth are you using? ^1.2.6 ### Provide environment information ```bash - OS: Mac Os 15.3.1 (24D70) - Browser: Brave Version 1.77.95 Chromium: 135.0.7049.52 (Official version) (arm64) ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { betterAuth } from 'better-auth'; import { drizzleAdapter } from 'better-auth/adapters/drizzle'; import { db } from './db/db'; import { admin, captcha, username } from 'better-auth/plugins'; import * as authSchema from './db/schema/auth'; export const auth = betterAuth({ basePath: '/auth', trustedOrigins: [ // ... ], advanced: { crossSubDomainCookies: { enabled: true, domain: process.env.BETTER_AUTH_COOKIE_DOMAIN, }, defaultCookieAttributes: { secure: true, httpOnly: true, sameSite: "none", // Allows CORS-based cookie sharing across subdomains partitioned: true, // New browser standards will mandate this for foreign cookies }, useSecureCookies: process.env.NODE_ENV === "production" }, database: drizzleAdapter(db, { provider: 'pg', schema: authSchema, }), emailVerification: { sendVerificationEmail: async ({ user, url }) => { // ... }, sendOnSignUp: true, expiresIn: 3600 // 1 hour }, emailAndPassword: { enabled: true, requireEmailVerification: true, sendResetPassword: async ({ user, url }) => { // ... }, }, socialProviders: { google: { clientId: process.env.GOOGLE_CLIENT_ID as string, clientSecret: process.env.GOOGLE_CLIENT_SECRET as string, }, }, account: { accountLinking: { enabled: true, trustedProviders: ['google'], }, }, plugins: [ username({ minUsernameLength: 3, maxUsernameLength: 20, }), admin(), captcha({ provider: 'cloudflare-turnstile', // or "google-recaptcha" secretKey: process.env.TURNSTILE_SECRET_KEY!, }), ], }); ``` ### Additional context I tested it on ^1.2.6 and ^1.2.5
GiteaMirror added the locked label 2026-04-13 04:27:03 -05:00
Author
Owner

@Kinfe123 commented on GitHub (Apr 14, 2025):

It is already fixed.

<!-- gh-comment-id:2800617788 --> @Kinfe123 commented on GitHub (Apr 14, 2025): It is already fixed.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#9111