plandex-ai/plandex · error
an org with domain %s already exists
Error message
an org with domain %s already exists
What it means
CreateOrg detects a unique-constraint violation (IsNonUniqueErr) on the INSERT INTO orgs and converts it to 'an org with domain %s already exists'. The orgs table has a unique index on domain; two orgs cannot claim the same email domain for auto-add.
Source
Thrown at app/server/db/org_helpers.go:109
}
return count > 0, nil
}
func CreateOrg(req *shared.CreateOrgRequest, userId string, domain *string, tx *sqlx.Tx) (*Org, error) {
org := &Org{
Name: req.Name,
Domain: domain,
AutoAddDomainUsers: req.AutoAddDomainUsers,
OwnerId: userId,
}
err := tx.QueryRow("INSERT INTO orgs (name, domain, auto_add_domain_users, owner_id, is_trial) VALUES ($1, $2, $3, $4, false) RETURNING id", req.Name, domain, req.AutoAddDomainUsers, userId).Scan(&org.Id)
if err != nil {
if IsNonUniqueErr(err) {
// Handle the uniqueness constraint violation
return nil, fmt.Errorf("an org with domain %s already exists", *domain)
}
return nil, fmt.Errorf("error creating org: %v", err)
}
orgOwnerRoleId, err := GetOrgOwnerRoleId()
if err != nil {
return nil, fmt.Errorf("error getting org owner role id: %v", err)
}
_, err = tx.Exec("INSERT INTO orgs_users (org_id, user_id, org_role_id) VALUES ($1, $2, $3)", org.Id, userId, orgOwnerRoleId)
if err != nil {
return nil, fmt.Errorf("error adding org membership: %v", err)
}
return org, nilView on GitHub (pinned to e2d772072e)
Solutions
- Catch this specific message and prompt the user to choose a different domain or join the existing org
- Check the domain first via GetOrgForDomain(domain) before calling CreateOrg and return a friendly 409-style response
- Use a subdomain-scoped or verified-domain scheme so distinct orgs don't collide on shared domains
- If the row is stale/unwanted, delete or update the existing org's domain, then retry
Example fix
// before
existing, err := db.GetOrgForDomain(domain)
// no check, straight to CreateOrg
org, err := db.CreateOrg(req, userId, &domain, tx)
// after
existing, err := db.GetOrgForDomain(domain)
if err != nil { return err }
if existing != nil {
return fmt.Errorf("domain %s is already claimed by org %s", domain, existing.Name)
}
org, err := db.CreateOrg(req, userId, &domain, tx) Defensive patterns
Strategy: validation
Validate before calling
existing, err := db.GetOrgForDomain(domain)
if err != nil { return err }
if existing != nil { return fmt.Errorf("domain %s already in use", domain) } Type guard
func isDuplicateDomainErr(err error) bool { return strings.Contains(err.Error(), "already exists") } Try / catch
org, err := db.CreateOrg(req, userId, &domain, tx)
if err != nil {
if strings.Contains(err.Error(), "already exists") {
return status.New(409, "domain already claimed by another org")
}
return err
} Prevention
- Check GetOrgForDomain before creating an org with a domain
- Disallow free email domains (gmail.com etc.) as org domains
- Make org creation idempotent per user (one org per owner/domain)
- Return a friendly 409 to clients rather than a raw DB error
When it happens
Trigger: Calling CreateOrg (e.g. from the create-org flow) with req.Domain set to a domain string that another org row already has — the INSERT fails with a Postgres 23505 unique_violation which IsNonUniqueErr matches.
Common situations: Two companies signing up from the same email domain (e.g. both gmail.com or a shared corporate domain); a user re-running an org-creation step after a partial failure; test environments sharing one database.
Related errors
- error getting org for domain: %v
- error adding convo tokens: %v
- error checking settings: %v
- error creating postgres driver: %v
- error validating org membership: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/ae417c751902b2ac.
Report an issue: GitHub.