flarum/framework · error · ValidationFailed

Username can only contain letters, numbers, underscores…

Error message

Username can only contain letters, numbers, underscores, and dashes.

What it means

AdminUser::validate() enforces that the admin username is non-empty and matches /^[a-z0-9_-]+$/i (letters, numbers, underscores, dashes only). Anything else — empty string, spaces, symbols, unicode — throws ValidationFailed during construction.

Solutions

  1. Enter a username using only A-Z, a-z, 0-9, '_' or '-'
  2. Trim and sanitize the input before constructing AdminUser
  3. Pre-validate with the same regex in the installer UI

Example fix

// before
new AdminUser('john doe!', $email, $password);
// after
$username = preg_replace('/[^a-z0-9_-]/i', '', $username);
if ($username !== '') { new AdminUser($username, $email, $password); }
Defensive patterns

Strategy: validation

Validate before calling

if ($username === '' || preg_match('/[^a-z0-9_-]/i', $username)) {
    throw new ValidationFailed('Username can only contain letters, numbers, underscores, and dashes.');
}

Type guard

function isValidUsername(?string $u): bool { return $u !== null && $u !== '' && preg_match('/^[a-z0-9_-]+$/i', $u) === 1; }

Try / catch

try {
    $admin = new AdminUser($username, $email, $password);
} catch (ValidationFailed $e) {
    $form->addError('username', $e->getMessage());
}

Prevention

When it happens

Trigger: Constructing AdminUser with '' or a username containing spaces or characters like '@', '.', '#', or accented letters.

Common situations: Users entering email-like usernames in the installer; copy-pasting names with spaces; localized usernames with non-ASCII characters.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of flarum/framework@4b939f6853 (2026-09-15). Data as JSON: /api/errors/53073b1af3308f44. Report an issue: GitHub.

Appendix: source

Thrown at framework/core/src/Install/AdminUser.php:48

    public function getAttributes(): array
    {
        return [
            'username' => $this->username,
            'email' => $this->email,
            'password' => (new BcryptHasher)->make($this->password),
            'joined_at' => Carbon::now(),
            'is_email_confirmed' => 1,
        ];
    }

    private function validate(): void
    {
        if (! filter_var($this->email, FILTER_VALIDATE_EMAIL)) {
            throw new ValidationFailed('You must enter a valid email.');
        }

        if (! $this->username || preg_match('/[^a-z0-9_-]/i', $this->username)) {
            throw new ValidationFailed('Username can only contain letters, numbers, underscores, and dashes.');
        }
    }
}

View on GitHub (pinned to 4b939f6853)