home-assistant/core · error · ValueError
Client_name is required for long-lived access token
Error message
Client_name is required for long-lived access token
What it means
Thrown by AuthManager.async_create_refresh_token (homeassistant/auth/__init__.py:494) when creating a TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN without a client_name. Long-lived tokens are surfaced in the UI by name, so the name is required and doubles as the uniqueness key.
Source
Thrown at homeassistant/auth/__init__.py:494
if token_type is models.TOKEN_TYPE_NORMAL:
expire_at = time.time() + REFRESH_TOKEN_EXPIRATION
else:
expire_at = None
if user.system_generated != (token_type == models.TOKEN_TYPE_SYSTEM):
raise ValueError(
"System generated users can only have system type refresh tokens"
)
if token_type == models.TOKEN_TYPE_NORMAL and client_id is None:
raise ValueError("Client is required to generate a refresh token.")
if (
token_type == models.TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN
and client_name is None
):
raise ValueError("Client_name is required for long-lived access token")
if token_type == models.TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN:
for token in user.refresh_tokens.values():
if (
token.client_name == client_name
and token.token_type == models.TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN
):
# Each client_name can only have one
# long_lived_access_token type of refresh token
raise ValueError(f"{client_name} already exists")
return await self._store.async_create_refresh_token(
user,
client_id,
client_name,
client_icon,
token_type,
access_token_expiration,View on GitHub (pinned to 58a3fdb3ea)
Solutions
- Provide a descriptive client_name, e.g. client_name="My script"
- Ensure it is unique among the user's existing long-lived token names to avoid the '{client_name} already exists' error next
Example fix
// before
await hass.auth.async_create_refresh_token(
user, token_type=models.TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN
)
# after
await hass.auth.async_create_refresh_token(
user,
token_type=models.TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN,
client_name="My script",
) Defensive patterns
Strategy: validation
Validate before calling
if token_type == models.TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN:
assert client_name
await hass.auth.async_create_refresh_token(
user, token_type=token_type, client_name=client_name
) Type guard
def long_lived_ready(token_type, client_name) -> bool:
return token_type is not models.TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN or bool(client_name) Prevention
- Treat client_name as a required field in any long-lived token UI or CLI
- Default it to a descriptive name so users can recognize the token later
When it happens
Trigger: Calling async_create_refresh_token(user, token_type=models.TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN, client_name=None).
Common situations: API wrappers that omit client_name; porting scripts that used only client_id for normal tokens.
Related errors
- {client_name} already exists
- User is not active
- System generated users cannot have refresh tokens connected
- System generated users can only have system type refresh tok
- Client is required to generate a refresh token.
AI-assisted analysis of home-assistant/core@58a3fdb3ea (2026-08-14).
Data as JSON: /api/errors/f1d52aaeb5803e9c.
Report an issue: GitHub.