{"record":{"id":"92f5bf61e91d3a75","repo":"plandex-ai/plandex","slug":"error-getting-org-owners-v","errorCode":null,"errorMessage":"error getting org owners: %v","messagePattern":"error getting org owners: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/server/db/rbac_helpers.go","lineNumber":46,"sourceCode":"\t\terr := cacheOrgMemberRoleId()\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"error getting org member role id: %v\", err)\n\t\t}\n\t}\n\n\tif orgMemberRoleId == \"\" {\n\t\treturn \"\", fmt.Errorf(\"org member role id is empty\")\n\t}\n\n\treturn orgMemberRoleId, nil\n}\n\nfunc GetOrgOwners(orgId string) ([]*User, error) {\n\tvar users []*User\n\terr := Conn.Select(&users, \"SELECT * FROM users WHERE id IN (SELECT user_id FROM orgs_users WHERE org_id = $1 AND org_role_id = $2)\", orgId, orgOwnerRoleId)\n\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error getting org owners: %v\", err)\n\t}\n\n\treturn users, nil\n}\n\nfunc CacheOrgRoleIds() error {\n\terr := cacheOrgOwnerRoleId()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error getting org owner role id: %v\", err)\n\n\t}\n\n\tif orgOwnerRoleId == \"\" {\n\t\tlog.Println(\"org owner role id is empty at startup\")\n\t}\n\n\terr = cacheOrgMemberRoleId()\n\tif err != nil {","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/db/rbac_helpers.go#L28-L64","documentation":"GetOrgOwners queries users whose orgs_users row has the owner role for the given org. The SELECT failed at the database level, so the raw driver error is wrapped with this message. Note the query reads the package global orgOwnerRoleId directly without ensuring it is cached, so it can also silently query with an empty role id (returning no owners) when caching never ran.","triggerScenarios":"Calling GetOrgOwners with an unreachable database, malformed query parameters, or before CacheOrgRoleIds populated orgOwnerRoleId (empty $2 yields zero owners instead of this error).","commonSituations":"DB outage during admin listing; calling the function in a fresh process before MustInitDb; orgId format mismatch (e.g. int vs uuid string) causing a SQL type error.","solutions":["Call GetOrgOwnerRoleId() first and pass its result explicitly instead of the raw global","Confirm CacheOrgRoleIds() ran at startup","Check DB connectivity and the wrapped inner error","Validate orgId is a valid, existing org id"],"exampleFix":"// before\nerr := Conn.Select(&users, \"SELECT * FROM users WHERE id IN (SELECT user_id FROM orgs_users WHERE org_id = $1 AND org_role_id = $2)\", orgId, orgOwnerRoleId)\n// after\nownerRoleId, err := GetOrgOwnerRoleId()\nif err != nil {\n\treturn nil, err\n}\nerr = Conn.Select(&users, \"SELECT * FROM users WHERE id IN (SELECT user_id FROM orgs_users WHERE org_id = $1 AND org_role_id = $2)\", orgId, ownerRoleId)","handlingStrategy":"validation","validationCode":"// ensure cache is populated before calling GetOrgOwners\nif err := CacheOrgRoleIds(); err != nil {\n\treturn err\n}\nowners, err := GetOrgOwners(orgId)","typeGuard":"func orgCacheReady() bool { return orgOwnerRoleId != \"\" }\n\nfunc canListOwners(orgId string) bool {\n\treturn orgId != \"\" && orgCacheReady()\n}","tryCatchPattern":"owners, err := GetOrgOwners(orgId)\nif err != nil {\n\tlog.Printf(\"GetOrgOwners failed for org %s: %v\", orgId, err)\n\treturn nil, fmt.Errorf(\"owner lookup unavailable: %w\", err)\n}\nif len(owners) == 0 {\n\tlog.Printf(\"warning: org %s has no owners (role id may be uncached)\", orgId)\n}","preventionTips":["Pass the resolved owner role id explicitly instead of reading the global","Call CacheOrgRoleIds() at process start","Validate orgId before querying","Treat zero owners as a warning signal of an empty orgOwnerRoleId"],"tags":["database","sql","rbac","query"],"backgroundTag":"sql-query-failed","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"}