{"record":{"id":"0a9efef86591a1ae","repo":"home-assistant/core","slug":"system-generated-users-cannot-have-refresh-tokens","errorCode":null,"errorMessage":"System generated users cannot have refresh tokens connected to a client.","messagePattern":"System generated users cannot have refresh tokens connected to a client\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"homeassistant/auth/__init__.py","lineNumber":466,"sourceCode":"                modules[module_id] = module.name\n        return modules\n\n    async def async_create_refresh_token(\n        self,\n        user: models.User,\n        client_id: str | None = None,\n        client_name: str | None = None,\n        client_icon: str | None = None,\n        token_type: str | None = None,\n        access_token_expiration: timedelta = ACCESS_TOKEN_EXPIRATION,\n        credential: models.Credentials | None = None,\n    ) -> models.RefreshToken:\n        \"\"\"Create a new refresh token for a user.\"\"\"\n        if not user.is_active:\n            raise ValueError(\"User is not active\")\n\n        if user.system_generated and client_id is not None:\n            raise ValueError(\n                \"System generated users cannot have refresh tokens connected \"\n                \"to a client.\"\n            )\n\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\"","sourceCodeStart":448,"sourceCodeEnd":484,"githubUrl":"https://github.com/home-assistant/core/blob/58a3fdb3ea0538617f0a07efcfba6294de64fd59/homeassistant/auth/__init__.py#L448-L484","documentation":"Thrown by AuthManager.async_create_refresh_token (homeassistant/auth/__init__.py:466) when a system-generated user is given a client_id. System-generated users may only hold system-type refresh tokens, which by definition are not bound to an OAuth client.","triggerScenarios":"Calling async_create_refresh_token(system_user, client_id=\"http://x\") — any non-None client_id for a user with system_generated=True.","commonSituations":"Generic token-issuing code paths that always pass a client_id; frontend code reusing the user token flow for integration/service accounts.","solutions":["Pass client_id=None for system-generated users","Branch the call: system users get no client metadata, human users get client_id from the auth flow"],"exampleFix":"// before\nawait hass.auth.async_create_refresh_token(system_user, client_id=client_id)\n\n# after\nawait hass.auth.async_create_refresh_token(\n    system_user,\n    client_id=None if system_user.system_generated else client_id,\n)","handlingStrategy":"validation","validationCode":"if user.system_generated:\n    assert client_id is None\nawait hass.auth.async_create_refresh_token(user, client_id=client_id)","typeGuard":"def valid_client_binding(user, client_id) -> bool:\n    return client_id is None or not user.system_generated","tryCatchPattern":null,"preventionTips":["Route system users through a token-creation path that never sets client metadata","Unit-test token issuance with both system and human users"],"tags":["auth","python","home-assistant","refresh-token","system-generated","valueerror"],"backgroundTag":null,"analyzedSha":"58a3fdb3ea0538617f0a07efcfba6294de64fd59","analyzedAt":"2026-08-14T20:54:38.818Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}