{"record":{"id":"014c8f14c38905ad","repo":"plandex-ai/plandex","slug":"error-getting-org-user-err-error","errorCode":null,"errorMessage":"Error getting org user: {err.Error()}","messagePattern":"Error getting org user: (.+?)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/handlers/users.go","lineNumber":135,"sourceCode":"\tif org.IsTrial {\n\t\twriteApiError(w, shared.ApiError{\n\t\t\tType:   shared.ApiErrorTypeTrialActionNotAllowed,\n\t\t\tStatus: http.StatusForbidden,\n\t\t\tMsg:    \"Trial user can't delete users\",\n\t\t})\n\t\treturn\n\t}\n\n\tvars := mux.Vars(r)\n\tuserId := vars[\"userId\"]\n\n\tlog.Println(\"userId: \", userId)\n\n\torgUser, err := db.GetOrgUser(userId, auth.OrgId)\n\n\tif err != nil {\n\t\tlog.Printf(\"Error getting org user: %v\\n\", err)\n\t\thttp.Error(w, \"Error getting org user: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\t// ensure current user can remove target user\n\tremovePermission := shared.Permission(strings.Join([]string{string(shared.PermissionRemoveUser), orgUser.OrgRoleId}, \"|\"))\n\n\tif !auth.HasPermission(removePermission) {\n\t\tlog.Printf(\"User does not have permission to remove user with role: %v\\n\", orgUser.OrgRoleId)\n\t\thttp.Error(w, \"User does not have permission to remove user with role: \"+orgUser.OrgRoleId, http.StatusForbidden)\n\t\treturn\n\t}\n\n\t// verify user is org member\n\tisMember, err := db.ValidateOrgMembership(userId, auth.OrgId)\n\n\tif err != nil {\n\t\tlog.Printf(\"Error validating org membership: %v\\n\", err)\n\t\thttp.Error(w, \"Error validating org membership: \"+err.Error(), http.StatusInternalServerError)","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/users.go#L117-L153","documentation":"The handler could not fetch the target org-user row via db.GetOrgUser(userId, auth.OrgId), so the permission check cannot be built. The error surfaces as HTTP 500 with the raw DB error appended, even though a missing target user is really a client-side 'not found' situation.","triggerScenarios":"Calling DELETE on a user whose userId path parameter has no corresponding org_user row for the authenticated org — wrong userId, user belongs to a different org, or the row was already deleted.","commonSituations":"Client passes an account-level userId instead of the org-scoped one; retrying an already-successful delete; userId casing/whitespace differences; user was removed concurrently.","solutions":["Confirm the userId path parameter matches an existing row in org_users for the caller's org","Treat sql.ErrNoRows as 404 instead of 500 so clients can detect 'already deleted'","Trim/normalize the userId before lookup and verify the client is using the org-scoped user id","Check for concurrent deletions if this occurs during retries"],"exampleFix":"// before\nif err != nil {\n    http.Error(w, \"Error getting org user: \"+err.Error(), http.StatusInternalServerError)\n    return\n}\n// after\nif errors.Is(err, sql.ErrNoRows) {\n    http.Error(w, \"org user not found\", http.StatusNotFound)\n    return\n} else if err != nil {\n    http.Error(w, \"internal error\", http.StatusInternalServerError)\n    return\n}","handlingStrategy":"validation","validationCode":"var exists bool\nerr := db.QueryRow(\n    \"SELECT EXISTS(SELECT 1 FROM org_users WHERE user_id=$1 AND org_id=$2)\",\n    userId, auth.OrgId).Scan(&exists)\nif err == nil && !exists {\n    return errors.New(\"target user not in this org\")\n}","typeGuard":"func orgUserExists(db *sqlx.DB, userId, orgId string) bool {\n    var ok bool\n    _ = db.Get(&ok, \"SELECT EXISTS(SELECT 1 FROM org_users WHERE user_id=$1 AND org_id=$2)\", userId, orgId)\n    return ok\n}","tryCatchPattern":"orgUser, err := db.GetOrgUser(userId, auth.OrgId)\nif err != nil {\n    if errors.Is(err, sql.ErrNoRows) {\n        http.Error(w, \"org user not found\", http.StatusNotFound)\n    } else {\n        http.Error(w, \"internal error\", http.StatusInternalServerError)\n    }\n    return\n}","preventionTips":["Validate the userId path parameter exists in the org before calling the delete endpoint","Treat 404/not-found distinctly from 500 in clients and stop retrying on not-found","Normalize userId strings (trim, consistent case) before lookup","Refresh the user list before each delete to avoid acting on stale data"],"tags":["go","database","http-500","user-management"],"backgroundTag":"record-not-found","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"}