home-assistant/core · error · InvalidUsername
username_already_exists
username_already_exists
Error message
username_already_exists
What it means
InvalidUsername with translation_key username_already_exists, raised by Data._validate_new_username (homeassistant/auth/providers/homeassistant.py:263) when the normalized new username equals an existing stored username (comparison is done on normalized forms, so 'Bob' collides with 'bob'). The placeholder username carries the rejected value.
Solutions
- Before creating, check `any(provider.data.normalize_username(u["username"]) == new_username.strip().casefold() for u in provider.data.users)` and skip
- For renames, first verify the target name is free; for imports, deduplicate names before writing
Example fix
// before
provider.data.add_auth("alice", password) # alice exists
# after
normalized = "alice"
if not any(provider.data.normalize_username(u["username"]) == normalized for u in provider.data.users):
provider.data.add_auth(normalized, password) Defensive patterns
Strategy: validation
Validate before calling
normalized = new_username.strip().casefold()
if not any(provider.data.normalize_username(u["username"]) == normalized for u in provider.data.users):
provider.data.add_auth(new_username, password) Type guard
def username_is_unique(provider_data, new_username: str) -> bool:
normalized = new_username.strip().casefold()
return not any(
provider_data.normalize_username(u["username"]) == normalized
for u in provider_data.users
) Try / catch
from homeassistant.auth.providers.homeassistant import InvalidUsername
try:
provider.data.add_auth(username, password)
except InvalidUsername as err:
if err.translation_key != "username_already_exists":
raise
# pick a different name or return the existing account Prevention
- Check name availability with a normalized comparison before creating
- Deduplicate names during imports and migrations
When it happens
Trigger: add_auth with a name already in the store; change_username to a name owned by another account; migration scripts re-creating existing users.
Common situations: Idempotent provisioning scripts that don't check first; renames colliding with another user; imports merging two sources with duplicate names.
Related errors
- username_not_normalized
- already exists
- user_not_found
- Client is required to generate a refresh token.
- Client_name is required for long-lived access token
AI-assisted analysis of home-assistant/core@58a3fdb3ea (2026-08-14).
Data as JSON: /api/errors/2dc53bc23fb26b09.
Report an issue: GitHub.
Appendix: source
Thrown at homeassistant/auth/providers/homeassistant.py:263
def _validate_new_username(self, new_username: str) -> None:
"""Validate that username is normalized and unique.
Raises InvalidUsername if the new username is invalid.
"""
normalized_username = self.normalize_username(
new_username, force_normalize=True
)
if normalized_username != new_username:
raise InvalidUsername(
translation_key="username_not_normalized",
translation_placeholders={"new_username": new_username},
)
if any(
self.normalize_username(user["username"]) == normalized_username
for user in self.users
):
raise InvalidUsername(
translation_key="username_already_exists",
translation_placeholders={"username": new_username},
)
@callback
def change_username(self, username: str, new_username: str) -> None:
"""Update the username.
Raises InvalidUser if user cannot be found.
Raises InvalidUsername if the new username is invalid.
"""
username = self.normalize_username(username)
self._validate_new_username(new_username)
for user in self.users:
if self.normalize_username(user["username"]) == username:
user["username"] = new_username
assert self._data is not NoneView on GitHub (pinned to 58a3fdb3ea)