From b28b9bb5b383cfc0a5a32b4723adb1eee2d60089 Mon Sep 17 00:00:00 2001 From: Piyush <296399266+skikken@users.noreply.github.com> Date: Thu, 10 Sep 2026 22:22:41 +0530 Subject: [PATCH 1/2] fix(Users): name allowed chars in username error The error shown when a username contains disallowed characters only asked for "a valid username" without saying what is valid. Multisite already names the allowed characters in wpmu_validate_user_signup(), so single site was the outlier. Update the message in register_new_user(), edit_user(), and the REST users controller. The REST copy deliberately keeps no HTML prefix, since REST error messages are plain text. Refs #17793 --- src/wp-admin/includes/user.php | 2 +- .../rest-api/endpoints/class-wp-rest-users-controller.php | 2 +- src/wp-includes/user.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wp-admin/includes/user.php b/src/wp-admin/includes/user.php index c6c08c4eaf76c..f6dd6d7cb08be 100644 --- a/src/wp-admin/includes/user.php +++ b/src/wp-admin/includes/user.php @@ -194,7 +194,7 @@ function edit_user( $user_id = 0 ) { } if ( ! $update && isset( $_POST['user_login'] ) && ! validate_username( $_POST['user_login'] ) ) { - $errors->add( 'user_login', __( 'Error: This username is invalid because it uses illegal characters. Please enter a valid username.' ) ); + $errors->add( 'user_login', __( 'Error: This username is invalid because it uses illegal characters. Usernames can only contain letters (a-z), numbers (0-9), dashes (-), underscores (_), and periods (.).' ) ); } if ( ! $update && username_exists( $user->user_login ) ) { diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php index 9b25cf7974cbc..a62c2ec11ae1e 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php @@ -1322,7 +1322,7 @@ public function check_username( $value, $request, $param ) { if ( ! validate_username( $username ) ) { return new WP_Error( 'rest_user_invalid_username', - __( 'This username is invalid because it uses illegal characters. Please enter a valid username.' ), + __( 'This username is invalid because it uses illegal characters. Usernames can only contain letters (a-z), numbers (0-9), dashes (-), underscores (_), and periods (.).' ), array( 'status' => 400 ) ); } diff --git a/src/wp-includes/user.php b/src/wp-includes/user.php index 6ce8dbf05175d..c188b3fda3f4d 100644 --- a/src/wp-includes/user.php +++ b/src/wp-includes/user.php @@ -3568,7 +3568,7 @@ function register_new_user( $user_login, $user_email ) { if ( '' === $sanitized_user_login ) { $errors->add( 'empty_username', __( 'Error: Please enter a username.' ) ); } elseif ( ! validate_username( $user_login ) ) { - $errors->add( 'invalid_username', __( 'Error: This username is invalid because it uses illegal characters. Please enter a valid username.' ) ); + $errors->add( 'invalid_username', __( 'Error: This username is invalid because it uses illegal characters. Usernames can only contain letters (a-z), numbers (0-9), dashes (-), underscores (_), and periods (.).' ) ); $sanitized_user_login = ''; } elseif ( username_exists( $sanitized_user_login ) ) { $errors->add( 'username_exists', __( 'Error: This username is already registered. Please choose another one.' ) ); From d2e3faee455fdc4210209334ceaa68df6df2095b Mon Sep 17 00:00:00 2001 From: Piyush <296399266+skikken@users.noreply.github.com> Date: Thu, 10 Sep 2026 22:22:41 +0530 Subject: [PATCH 2/2] test(Users): cover invalid username error message The REST users controller test pinned the old string with assertSame(), so it needed updating. Add coverage for the registration path, for an accented username and for a disallowed symbol. Refs #17793 --- .../tests/rest-api/rest-users-controller.php | 2 +- tests/phpunit/tests/user.php | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/tests/phpunit/tests/rest-api/rest-users-controller.php b/tests/phpunit/tests/rest-api/rest-users-controller.php index 86ec4b8048551..0d3af1d1ebcd6 100644 --- a/tests/phpunit/tests/rest-api/rest-users-controller.php +++ b/tests/phpunit/tests/rest-api/rest-users-controller.php @@ -1416,7 +1416,7 @@ public function test_create_item_invalid_username() { $this->assertIsArray( $data['data']['params'] ); $errors = $data['data']['params']; $this->assertIsString( $errors['username'] ); - $this->assertSame( 'This username is invalid because it uses illegal characters. Please enter a valid username.', $errors['username'] ); + $this->assertSame( 'This username is invalid because it uses illegal characters. Usernames can only contain letters (a-z), numbers (0-9), dashes (-), underscores (_), and periods (.).', $errors['username'] ); } } diff --git a/tests/phpunit/tests/user.php b/tests/phpunit/tests/user.php index f600adbcb1164..2f710f7994788 100644 --- a/tests/phpunit/tests/user.php +++ b/tests/phpunit/tests/user.php @@ -1202,6 +1202,39 @@ public function test_illegal_user_logins_single_wp_create_user( $user_login ) { $this->assertInstanceOf( 'WP_User', $user ); } + /** + * The error message for an invalid username should tell the user which + * characters are allowed. + * + * @ticket 17793 + * @dataProvider data_invalid_usernames + * + * @param string $user_login A username that contains disallowed characters. + */ + public function test_register_new_user_invalid_username_message( $user_login ) { + $response = register_new_user( $user_login, 'testuser@example.com' ); + + $this->assertInstanceOf( 'WP_Error', $response ); + $this->assertSame( 'invalid_username', $response->get_error_code() ); + + $this->assertStringContainsString( + 'Usernames can only contain letters (a-z), numbers (0-9), dashes (-), underscores (_), and periods (.).', + $response->get_error_message() + ); + } + + /** + * Data provider for test_register_new_user_invalid_username_message(). + * + * @return array[] Test parameters. + */ + public function data_invalid_usernames() { + return array( + 'accented characters' => array( 'jösé' ), + 'disallowed symbol' => array( 'testuser*' ), + ); + } + /** * @ticket 27317 * @group ms-required