{"record":{"id":"0f962152db1f76d7","repo":"plandex-ai/plandex","slug":"error-getting-owner-role-id-v","errorCode":null,"errorMessage":"error getting owner role id: %v","messagePattern":"error getting owner role id: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/server/db/rbac_helpers.go","lineNumber":80,"sourceCode":"\n\terr = cacheOrgMemberRoleId()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error getting org member role id: %v\", err)\n\t}\n\n\tif orgMemberRoleId == \"\" {\n\t\tlog.Println(\"org member role id is empty at startup\")\n\t}\n\n\treturn nil\n}\n\nfunc cacheOrgOwnerRoleId() error {\n\tvar roleId string\n\terr := Conn.Get(&roleId, \"SELECT id FROM org_roles WHERE name = 'owner'\")\n\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error getting owner role id: %v\", err)\n\t}\n\n\torgOwnerRoleId = roleId\n\n\treturn nil\n}\n\nfunc cacheOrgMemberRoleId() error {\n\tvar roleId string\n\terr := Conn.Get(&roleId, \"SELECT id FROM org_roles WHERE name = 'member'\")\n\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error getting member role id: %v\", err)\n\t}\n\n\torgMemberRoleId = roleId\n\n\treturn nil","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/db/rbac_helpers.go#L62-L98","documentation":"cacheOrgOwnerRoleId performs 'SELECT id FROM org_roles WHERE name = owner' via Conn.Get. Any driver-level failure — no rows (sql.ErrNoRows), connection error, or query error — is wrapped with this message and propagated up through GetOrgOwnerRoleId and CacheOrgRoleIds. It is the lowest-level RBAC lookup failure.","triggerScenarios":"First GetOrgOwnerRoleId/CacheOrgRoleIds call in a process where org_roles is empty or absent, the DB is down, or Conn is nil.","commonSituations":"sql.ErrNoRows from an unseeded database; connection refused after a DB restart; migrations pending on a new environment.","solutions":["Insert the 'owner' row: INSERT INTO org_roles (name) VALUES ('owner');","Run pending migrations creating/seeding org_roles","Check the inner error: sql.ErrNoRows means data missing, ping failure means connectivity","Ensure MustInitDb/Conn initialization precedes any call"],"exampleFix":"// before\nvar roleId string\nerr := Conn.Get(&roleId, \"SELECT id FROM org_roles WHERE name = 'owner'\")\n// after\nvar roleId string\nerr := Conn.Get(&roleId, \"SELECT id FROM org_roles WHERE name = 'owner'\")\nif errors.Is(err, sql.ErrNoRows) {\n\treturn fmt.Errorf(\"org_roles 'owner' row missing — run seed migrations\")\n}","handlingStrategy":"retry","validationCode":"var n int\nerr := db.QueryRow(\"SELECT count(*) FROM org_roles WHERE name = 'owner'\").Scan(&n)\nif err != nil || n == 0 {\n\treturn fmt.Errorf(\"owner role row missing\")\n}","typeGuard":"func isNoRows(err error) bool {\n\treturn err != nil && (errors.Is(err, sql.ErrNoRows) || strings.Contains(err.Error(), \"sql: no rows\"))\n}","tryCatchPattern":"roleId, err := GetOrgOwnerRoleId()\nif err != nil {\n\tif isNoRows(err) {\n\t\treturn retryWithBackoff(3, func() error { // only useful after seeding\n\t\t\t_, e := GetOrgOwnerRoleId()\n\t\t\treturn e\n\t\t})\n\t}\n\treturn fmt.Errorf(\"db connectivity issue: %w\", err)\n}","preventionTips":["Check errors.Is(err, sql.ErrNoRows) to separate data vs connectivity issues","Ping the DB in health checks","Keep role seed data in migrations, not manual SQL"],"tags":["database","sql","rbac","no-rows"],"backgroundTag":"sql-no-rows","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}