{"record":{"id":"f177f754368d740a","repo":"infiniflow/ragflow","slug":"400","errorCode":"400","errorMessage":"Exist more than 1 user: {username}!","messagePattern":"Exist more than 1 user: (.+?)!","errorType":"http","errorClass":"AdminException","httpStatus":400,"severity":"error","filePath":"admin/server/services.py","lineNumber":241,"sourceCode":"            raise AdminException(f\"Exist more than 1 user: {username}!\")\n        # check activate status different from new\n        usr = user_list[0]\n        if not usr.is_superuser:\n            return f\"{usr} isn't superuser, yet!\"\n        # update is_active\n        UserService.update_user(usr.id, {\"is_superuser\": False})\n        return \"Revoke successfully!\"\n\n\nclass UserServiceMgr:\n    @staticmethod\n    def get_user_datasets(username):\n        # use email to find user.\n        user_list = UserService.query_user_by_email(username)\n        if not user_list:\n            raise UserNotFoundError(username)\n        elif len(user_list) > 1:\n            raise AdminException(f\"Exist more than 1 user: {username}!\")\n        # find tenants\n        usr = user_list[0]\n        tenants = TenantService.get_joined_tenants_by_user_id(usr.id)\n        tenant_ids = [m[\"tenant_id\"] for m in tenants]\n        # filter permitted kb and owned kb\n        return KnowledgebaseService.get_all_kb_by_tenant_ids(tenant_ids, usr.id)\n\n    @staticmethod\n    def get_user_agents(username):\n        # use email to find user.\n        user_list = UserService.query_user_by_email(username)\n        if not user_list:\n            raise UserNotFoundError(username)\n        elif len(user_list) > 1:\n            raise AdminException(f\"Exist more than 1 user: {username}!\")\n        # find tenants\n        usr = user_list[0]\n        tenants = TenantService.get_joined_tenants_by_user_id(usr.id)","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/admin/server/services.py#L223-L259","documentation":"AdminException (HTTP 400) raised by UserServiceMgr.get_user_datasets (admin/server/services.py:241) when the email matches multiple user rows. The listing derives tenant ids from user_list[0]; with duplicates it could return another account's knowledge bases, so the ambiguous query is refused.","triggerScenarios":"Duplicate user rows share one email; every get_user_datasets call for that address fails before TenantService is consulted.","commonSituations":"Imported/migrated data with duplicated accounts; no unique index on email; concurrent provisioning races during first SSO login.","solutions":["Enumerate duplicates: SELECT id, email FROM user WHERE email = '<username>';","Dedupe to a single row per email.","Add a unique constraint on the email column.","Retry the dataset listing."],"exampleFix":"-- before\nSELECT COUNT(*) FROM user WHERE email='user@example.com';  -- >1, listing fails\n-- after\nDELETE FROM user WHERE email='user@example.com' AND id <> '<intended-id>';\nALTER TABLE user ADD UNIQUE KEY uq_user_email (email);","handlingStrategy":"validation","validationCode":"from api.db.services import UserService\n\ndef assert_unique_target(email: str) -> None:\n    users = UserService.query_user_by_email(email)\n    if len(users) != 1:\n        raise RuntimeError(f'{email}: {len(users)} rows; dataset listing ambiguous')","typeGuard":null,"tryCatchPattern":"from admin.server.exceptions import AdminException\ntry:\n    kbs = UserServiceMgr.get_user_datasets(email)\nexcept AdminException as e:\n    if 'more than 1 user' in e.message.lower():\n        raise RuntimeError('duplicate users; dedupe before listing datasets') from e\n    raise","preventionTips":["Prevent duplicate email rows with a unique index.","Audit for duplicates after imports and migrations.","Resolve the account to a single id before any tenant-scoped listing."],"tags":["data-integrity","duplicate-users","admin-api","datasets"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}