{"record":{"id":"ae417c751902b2ac","repo":"plandex-ai/plandex","slug":"an-org-with-domain-s-already-exists","errorCode":null,"errorMessage":"an org with domain %s already exists","messagePattern":"an org with domain (.+?) already exists","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/server/db/org_helpers.go","lineNumber":109,"sourceCode":"\t}\n\n\treturn count > 0, nil\n}\n\nfunc CreateOrg(req *shared.CreateOrgRequest, userId string, domain *string, tx *sqlx.Tx) (*Org, error) {\n\torg := &Org{\n\t\tName:               req.Name,\n\t\tDomain:             domain,\n\t\tAutoAddDomainUsers: req.AutoAddDomainUsers,\n\t\tOwnerId:            userId,\n\t}\n\n\terr := 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)\n\n\tif err != nil {\n\t\tif IsNonUniqueErr(err) {\n\t\t\t// Handle the uniqueness constraint violation\n\t\t\treturn nil, fmt.Errorf(\"an org with domain %s already exists\", *domain)\n\n\t\t}\n\n\t\treturn nil, fmt.Errorf(\"error creating org: %v\", err)\n\t}\n\n\torgOwnerRoleId, err := GetOrgOwnerRoleId()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error getting org owner role id: %v\", err)\n\t}\n\n\t_, err = tx.Exec(\"INSERT INTO orgs_users (org_id, user_id, org_role_id) VALUES ($1, $2, $3)\", org.Id, userId, orgOwnerRoleId)\n\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error adding org membership: %v\", err)\n\t}\n\n\treturn org, nil","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/db/org_helpers.go#L91-L127","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nexisting, err := db.GetOrgForDomain(domain)\n// no check, straight to CreateOrg\norg, err := db.CreateOrg(req, userId, &domain, tx)\n// after\nexisting, err := db.GetOrgForDomain(domain)\nif err != nil { return err }\nif existing != nil {\n    return fmt.Errorf(\"domain %s is already claimed by org %s\", domain, existing.Name)\n}\norg, err := db.CreateOrg(req, userId, &domain, tx)","handlingStrategy":"validation","validationCode":"existing, err := db.GetOrgForDomain(domain)\nif err != nil { return err }\nif existing != nil { return fmt.Errorf(\"domain %s already in use\", domain) }","typeGuard":"func isDuplicateDomainErr(err error) bool { return strings.Contains(err.Error(), \"already exists\") }","tryCatchPattern":"org, err := db.CreateOrg(req, userId, &domain, tx)\nif err != nil {\n    if strings.Contains(err.Error(), \"already exists\") {\n        return status.New(409, \"domain already claimed by another org\")\n    }\n    return err\n}","preventionTips":["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"],"tags":["postgresql","unique-constraint","duplicate","org-domain"],"backgroundTag":"duplicate-key-constraint-violation","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}