plandex-ai/plandex · error · http

User email does not match

Error message

User email does not match

What it means

CreateEmailVerificationHandler returns HTTP 400 'User email does not match' when a UserId is supplied and the email stored for that user does not equal the request Email (after lowercasing). The handler requires the (userId, email) pair to be consistent before issuing a verification pin, protecting against sending pins to an address that does not own the account.

Source

Thrown at app/server/handlers/sessions.go:68

		hasAccount = true

		user, err := db.GetUser(req.UserId)

		if err != nil {
			log.Printf("Error getting user: %v\n", err)
			http.Error(w, "Error getting user: "+err.Error(), http.StatusInternalServerError)
			return
		}

		if user == nil {
			log.Printf("User not found for id: %v\n", req.UserId)
			http.Error(w, "User not found", http.StatusNotFound)
			return
		}

		if user.Email != req.Email {
			log.Printf("User email does not match for id: %v\n", req.UserId)
			http.Error(w, "User email does not match", http.StatusBadRequest)
			return
		}
	}

	if req.RequireUser && !hasAccount {
		log.Printf("User not found for email: %v\n", req.Email)
		http.Error(w, "User not found", http.StatusNotFound)
		return
	} else if req.RequireNoUser && hasAccount {
		log.Printf("User already exists for email: %v\n", req.Email)
		http.Error(w, "User already exists", http.StatusConflict)
		return
	}

	var res shared.CreateEmailVerificationResponse

	if !(os.Getenv("GOENV") == "development" && os.Getenv("LOCAL_MODE") == "1") {
		// create pin - 6 alphanumeric characters

View on GitHub (pinned to e2d772072e)

Solutions

  1. Log the user out / clear stored credentials and have them re-enter the exact email registered to the account.
  2. Call an account-info endpoint (or query the DB) to confirm the email associated with the UserId and use that email in the request.
  3. Normalize the email client-side (strings.ToLower(strings.TrimSpace(email))) before sending so casing/whitespace never mismatches.
  4. If the user wants to change to the new email, use the proper email-change flow (which verifies the new address) rather than CreateEmailVerification with a mismatched pair.
  5. Remove the UserId from the request if the goal is just an account-existence check by email; then the handler looks up by email only.

Example fix

// before
req := shared.CreateEmailVerificationRequest{ UserId: userID, Email: typedEmail }
// after
req := shared.CreateEmailVerificationRequest{
    UserId: userID,
    Email:  strings.ToLower(strings.TrimSpace(typedEmail)), // must equal user.Email
}
if storedEmailForUser(userID) != req.Email {
    // route to email-change flow instead
}
Defensive patterns

Strategy: validation

Validate before calling

// normalize and confirm the email matches what the server has for this user
email := strings.ToLower(strings.TrimSpace(inputEmail))
if req.UserId != "" && email != storedEmailForUser(req.UserId) {
    // mismatch: use the stored email or route to the email-change flow
    req.Email = storedEmailForUser(req.UserId)
}

Try / catch

resp, err := http.Post(url, "application/json", body)
if err != nil { return err }
if resp.StatusCode == http.StatusBadRequest {
    // email/userId pair inconsistent: clear stored pair and prompt user to re-enter email
    clearStoredEmail()
    return promptUserForEmail()
}

Prevention

When it happens

Trigger: POSTing CreateEmailVerificationRequest with a valid UserId but an Email field different from the user's registered email; omitting the Email field entirely (empty string never matches); sending mixed-case email that lowercases to something different from the stored address (rare if stored normalized).

Common situations: Client uses a different personal email for sign-in attempt than the one registered (user forgot which email they signed up with); client sends userId but leaves email blank; a bug where the client fetches one user's ID and another's email; after an email change, the client still caches the old address.

Related errors


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/e326713ade312426. Report an issue: GitHub.