{"record":{"id":"f2654b3c9f883fd7","repo":"plandex-ai/plandex","slug":"error-adding-org-user-v","errorCode":null,"errorMessage":"error adding org user: %v","messagePattern":"error adding org user: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/server/db/org_helpers.go","lineNumber":237,"sourceCode":"\nfunc AddToOrgForDomain(userId, domain string, tx *sqlx.Tx) (string, error) {\n\torg, err := GetOrgForDomain(domain)\n\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error getting org for domain: %v\", err)\n\t}\n\n\torgOwnerRoleId, err := GetOrgOwnerRoleId()\n\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error getting org owner role id: %v\", err)\n\t}\n\n\tif org != nil && org.AutoAddDomainUsers {\n\t\terr = CreateOrgUser(org.Id, userId, orgOwnerRoleId, tx)\n\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"error adding org user: %v\", err)\n\t\t}\n\t}\n\n\tvar orgId string\n\tif org != nil {\n\t\torgId = org.Id\n\t}\n\n\treturn orgId, nil\n}\n","sourceCodeStart":219,"sourceCodeEnd":248,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/db/org_helpers.go#L219-L248","documentation":"AddToOrgForDomain wraps an error returned by CreateOrgUser(org.Id, userId, orgOwnerRoleId, tx) with this message. The inner error is the INSERT INTO orgs_users failure (see the 'error adding org member' wrap), re-labeled here with account-creation context.","triggerScenarios":"During CreateAccount, the org matched by the user's email domain has AutoAddDomainUsers=true and CreateOrgUser's INSERT fails — typically org_user_unique duplicate (user already added concurrently or earlier), invalid org_owner role id FK, or DB error.","commonSituations":"User re-signs up or a retry double-adds them to the domain org; owner-role id lookup returned a stale/invalid value; transaction rolled back due to an earlier error in the same tx; Postgres constraint org_user_unique blocks the insert.","solutions":["Inspect the nested cause: unique-constraint on org_user_unique means the user is already a member — use ON CONFLICT DO NOTHING or treat as success","Ensure orgOwnerRoleId is a valid org_roles.id (GetOrgOwnerRoleId result not stale)","Check the transaction state — if WithTx already failed, fix the root error instead of the insert","Verify org.Id/userId exist in orgs/users to rule out FK violations"],"exampleFix":"// before\nquery := \"INSERT INTO orgs_users (org_id, user_id, org_role_id) VALUES ($1, $2, $3)\"\n// after\nquery := \"INSERT INTO orgs_users (org_id, user_id, org_role_id) VALUES ($1, $2, $3) ON CONFLICT ON CONSTRAINT org_user_unique DO NOTHING\"","handlingStrategy":"try-catch","validationCode":"var exists bool\nConn.Get(&exists, \"SELECT EXISTS(SELECT 1 FROM orgs_users WHERE org_id=$1 AND user_id=$2)\", org.Id, userId)\n// skip CreateOrgUser if exists","typeGuard":null,"tryCatchPattern":"if err := CreateOrgUser(org.Id, userId, orgOwnerRoleId, tx); err != nil {\n    if strings.Contains(err.Error(), \"org_user_unique\") {\n        return org.Id, nil // already a member — treat as success\n    }\n    return \"\", fmt.Errorf(\"error adding org user: %v\", err)\n}","preventionTips":["Make domain auto-add idempotent with ON CONFLICT DO NOTHING","Only call inside an active, unfailed transaction","Verify AutoAddDomainUsers orgs have valid role ids","Log the nested cause — this wrap hides the real constraint error"],"tags":["database","postgres","insert","unique-constraint","transaction","go"],"backgroundTag":"postgres-unique-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"}