bytedance/deer-flow · warning · HTTPException
email_already_exists
email_already_exists
Error message
Email already registered
What it means
400 from POST /api/auth/register: the local provider's create_user raised ValueError, which this route interprets as a unique-email constraint violation — the submitted email already has an account. The body carries code 'email_already_exists'. Auto-login never happens on this path.
Source
Thrown at backend/app/gateway/routers/auth.py:361
@router.post("/register", response_model=UserResponse, status_code=status.HTTP_201_CREATED)
async def register(request: Request, response: Response, body: RegisterRequest):
"""Register a new user account (always 'user' role).
The first admin is created explicitly through /initialize. This endpoint creates regular users.
Auto-login by setting the session cookie.
Returns 403 when ``auth.local.allow_registration`` is false.
"""
if not _local_registration_enabled():
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail=AuthErrorResponse(code=AuthErrorCode.REGISTRATION_DISABLED, message="Self-registration is disabled on this deployment").model_dump(),
)
try:
user = await get_local_provider().create_user(email=body.email, password=body.password, system_role="user")
except ValueError:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=AuthErrorResponse(code=AuthErrorCode.EMAIL_ALREADY_EXISTS, message="Email already registered").model_dump(),
)
token = create_access_token(str(user.id), token_version=user.token_version)
_set_session_cookie(response, token, request, remember_me=body.remember_me)
return UserResponse(id=str(user.id), email=user.email, system_role=user.system_role, oauth_provider=user.oauth_provider)
@router.post("/logout", response_model=MessageResponse)
async def logout(request: Request, response: Response):
"""Logout current user by clearing the cookie."""
is_https = is_secure_request(request)
response.delete_cookie(key=ACCESS_TOKEN_COOKIE_NAME, secure=is_https, samesite="lax")
response.delete_cookie(key=CSRF_COOKIE_NAME, secure=is_https, samesite="strict")
response.delete_cookie(key=SESSION_PERSISTENCE_COOKIE_NAME, secure=is_https, samesite="lax")
setattr(request.state, SKIP_AUTH_CSRF_COOKIE_STATE_ATTR, True)View on GitHub (pinned to 1dd6ba1acb)
Solutions
- Log in with the existing account instead of registering again
- Use password reset if ownership of the email is yours but the password is unknown
- Administrators can delete or rename the pre-existing account if the collision is unintended
- Guard the signup form with a duplicate-email check or clear messaging on this 400
Defensive patterns
Strategy: try-catch
Validate before calling
const taken = await checkEmailAvailable(email); // if exposed if (taken) suggestLoginInstead();
Try / catch
try { await register(email, pw); } catch (e) { if (e.status === 400 && e.body?.code === 'email_already_exists') { redirect('/login', {email}); return; } throw e; } Prevention
- Disable the submit button while the register request is in flight (prevents double-submit duplicates)
- On this 400, route users to login or password reset rather than a generic failure
When it happens
Trigger: Registering with an email that already exists in the user store, including one created via OAuth/SSO with the same address.
Common situations: Double-submitting the signup form; re-registering after a previous attempt succeeded; SSO users trying to create a local password account with their IdP email.
Related errors
- registration_disabled
- Invalid provider ID
- Unknown SSO provider: {provider}
- Failed to update agent: ${res.statusText}
- Unable to recover SSE history after ${recoveryAttempts} atte
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/8903a8ae21b6baa5.
Report an issue: GitHub.