plandex-ai/plandex · error
error creating account: %v
Error message
error creating account: %v
What it means
The create-account HTTP handler wraps any failure from db.CreateAccount inside its WithTx transaction with this message. It is an aggregate wrapper: the real cause (invalid email, duplicate user, DB failure) is nested inside the wrapped error text.
Source
Thrown at app/server/handlers/accounts.go:71
if err != nil {
log.Printf("Error validating email verification: %v\n", err)
http.Error(w, "Error validating email verification: "+err.Error(), http.StatusInternalServerError)
return
}
}
var apiErr *shared.ApiError
var user *db.User
var userId string
var token string
var orgId string
err = db.WithTx(r.Context(), "create account", func(tx *sqlx.Tx) error {
res, err := db.CreateAccount(req.UserName, req.Email, emailVerificationId, tx)
if err != nil {
return fmt.Errorf("error creating account: %v", err)
}
user = res.User
userId = user.Id
token = res.Token
orgId = res.OrgId
_, apiErr = hooks.ExecHook(hooks.CreateAccount, hooks.HookParams{
Auth: &types.ServerAuth{
User: user,
OrgId: orgId,
},
})
return nil
})
if apiErr != nil {View on GitHub (pinned to e2d772072e)
Solutions
- Read the full chained error text to find the root cause (the inner %v contains the db-level reason)
- If the inner error says 'user already exists', direct the user to sign in instead (409)
- Validate req.UserName and req.Email before invoking the handler logic
- Check database health if the inner error is a connection/query failure
- Retry only for transient inner errors; transaction rollback guarantees no partial account
Example fix
// before
return fmt.Errorf("error creating account: %v", err)
// after
return fmt.Errorf("error creating account: %w", err) // unwrap to distinguish duplicate vs db failure Defensive patterns
Strategy: try-catch
Validate before calling
if req.UserName == "" || !validEmail(req.Email) {
http.Error(w, "invalid name or email", http.StatusBadRequest); return
} Try / catch
if err := db.WithTx(r.Context(), "create account", func(tx *sqlx.Tx) error {
res, err := db.CreateAccount(req.UserName, req.Email, emailVerificationId, tx)
if err != nil {
if strings.Contains(err.Error(), "user already exists") { return errEmailTaken } // → 409
return fmt.Errorf("error creating account: %w", err)
}
return nil
}); err != nil {
if errors.Is(err, errEmailTaken) { http.Error(w, "account exists", http.StatusConflict); return }
http.Error(w, err.Error(), http.StatusInternalServerError)
} Prevention
- Validate request payload before starting the transaction
- Distinguish duplicate-account (409) from infra failures (5xx) by unwrapping the chained error
- Keep WithTx transactions short to avoid aborted-tx cascades
- Log the innermost cause, not just the wrapper
When it happens
Trigger: A POST to the account-creation endpoint where CreateAccount fails — e.g. CreateUser returned invalid email or duplicate email, token/org creation failed, or the surrounding WithTx transaction was rolled back.
Common situations: Duplicate sign-up attempt (surfaces 'error creating account: user already exists for email: ...'), malformed sign-up payload, or database outage during registration.
Related errors
- error renaming plan: %v
- error updating plan active branches: %v
- Error marshalling users: {err.Error()}
- connection to plan stream timed out due to missing heartbeat
- error loading accounts: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/bb4d9421738464e7.
Report an issue: GitHub.