{"record":{"id":"2f25758cfef80773","repo":"home-assistant/core","slug":"client-is-required-to-generate-a-refresh-token","errorCode":null,"errorMessage":"Client is required to generate a refresh token.","messagePattern":"Client is required to generate a refresh token\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"homeassistant/auth/__init__.py","lineNumber":488,"sourceCode":"\n        if token_type is None:\n            if user.system_generated:\n                token_type = models.TOKEN_TYPE_SYSTEM\n            else:\n                token_type = models.TOKEN_TYPE_NORMAL\n\n        if token_type is models.TOKEN_TYPE_NORMAL:\n            expire_at = time.time() + REFRESH_TOKEN_EXPIRATION\n        else:\n            expire_at = None\n\n        if user.system_generated != (token_type == models.TOKEN_TYPE_SYSTEM):\n            raise ValueError(\n                \"System generated users can only have system type refresh tokens\"\n            )\n\n        if token_type == models.TOKEN_TYPE_NORMAL and client_id is None:\n            raise ValueError(\"Client is required to generate a refresh token.\")\n\n        if (\n            token_type == models.TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN\n            and client_name is None\n        ):\n            raise ValueError(\"Client_name is required for long-lived access token\")\n\n        if token_type == models.TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN:\n            for token in user.refresh_tokens.values():\n                if (\n                    token.client_name == client_name\n                    and token.token_type == models.TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN\n                ):\n                    # Each client_name can only have one\n                    # long_lived_access_token type of refresh token\n                    raise ValueError(f\"{client_name} already exists\")\n\n        return await self._store.async_create_refresh_token(","sourceCodeStart":470,"sourceCodeEnd":506,"githubUrl":"https://github.com/home-assistant/core/blob/58a3fdb3ea0538617f0a07efcfba6294de64fd59/homeassistant/auth/__init__.py#L470-L506","documentation":"Thrown by AuthManager.async_create_refresh_token (homeassistant/auth/__init__.py:488) when token_type is TOKEN_TYPE_NORMAL but client_id is None. Normal (short-lived, refreshable) tokens are always bound to the OAuth client that requested them, so a client_id is mandatory.","triggerScenarios":"Calling async_create_refresh_token(user) or with client_id=None while token_type stays TOKEN_TYPE_NORMAL (the default for non-system users).","commonSituations":"Test code minting tokens without a client; scripts forgetting to forward the client_id from the auth flow step data; using long-lived-token style calls (no client_id) but leaving token_type at its default.","solutions":["Pass the client_id of the requesting client: `await hass.auth.async_create_refresh_token(user, client_id)`","If you intend a long-lived token, pass token_type=models.TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN together with a client_name instead"],"exampleFix":"// before\nrefresh_token = await hass.auth.async_create_refresh_token(user, client_id=None)\n\n# after\nrefresh_token = await hass.auth.async_create_refresh_token(user, client_id=\"https://my.example.app\")","handlingStrategy":"validation","validationCode":"if token_type == models.TOKEN_TYPE_NORMAL:\n    assert client_id is not None\nawait hass.auth.async_create_refresh_token(user, client_id=client_id)","typeGuard":"def has_required_client(token_type, client_id) -> bool:\n    return token_type is not models.TOKEN_TYPE_NORMAL or client_id is not None","tryCatchPattern":null,"preventionTips":["Forward the client_id from the auth flow step data whenever issuing normal tokens","If you need a token without a client, create a long-lived access token with a client_name instead"],"tags":["auth","python","home-assistant","refresh-token","client-id","valueerror"],"backgroundTag":null,"analyzedSha":"58a3fdb3ea0538617f0a07efcfba6294de64fd59","analyzedAt":"2026-08-14T20:54:38.818Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}