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

  1. Log in with the existing account instead of registering again
  2. Use password reset if ownership of the email is yours but the password is unknown
  3. Administrators can delete or rename the pre-existing account if the collision is unintended
  4. 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

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


AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14). Data as JSON: /api/errors/8903a8ae21b6baa5. Report an issue: GitHub.