{"record":{"id":"9f9ec0543007a5f1","repo":"bytebase/bytebase","slug":"codeinternal-9f9ec0","errorCode":"CodeInternal","errorMessage":"failed to list roles","messagePattern":"failed to list roles","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/api/v1/role_service.go","lineNumber":43,"sourceCode":"\tstore          *store.Store\n\tiamManager     *iam.Manager\n\tlicenseService *enterprise.LicenseService\n}\n\n// NewRoleService returns a new instance of the role service.\nfunc NewRoleService(store *store.Store, iamManager *iam.Manager, licenseService *enterprise.LicenseService) *RoleService {\n\treturn &RoleService{\n\t\tstore:          store,\n\t\tiamManager:     iamManager,\n\t\tlicenseService: licenseService,\n\t}\n}\n\n// ListRoles lists roles.\nfunc (s *RoleService) ListRoles(ctx context.Context, _ *connect.Request[v1pb.ListRolesRequest]) (*connect.Response[v1pb.ListRolesResponse], error) {\n\troleMessages, err := s.store.ListRoles(ctx, &store.FindRoleMessage{Workspace: common.GetWorkspaceIDFromContext(ctx)})\n\tif err != nil {\n\t\treturn nil, connect.NewError(connect.CodeInternal, errors.Wrap(err, \"failed to list roles\"))\n\t}\n\treturn connect.NewResponse(&v1pb.ListRolesResponse{\n\t\tRoles: convertToRoles(roleMessages),\n\t}), nil\n}\n\n// GetRole gets a role.\nfunc (s *RoleService) GetRole(ctx context.Context, req *connect.Request[v1pb.GetRoleRequest]) (*connect.Response[v1pb.Role], error) {\n\troleName := req.Msg.Name\n\troleID, err := common.GetRoleID(roleName)\n\tif err != nil {\n\t\treturn nil, connect.NewError(connect.CodeInvalidArgument, err)\n\t}\n\trole, err := s.store.GetRole(ctx, &store.FindRoleMessage{Workspace: common.GetWorkspaceIDFromContext(ctx), ResourceID: &roleID})\n\tif err != nil {\n\t\treturn nil, connect.NewError(connect.CodeInternal, errors.Wrap(err, \"failed to get role\"))\n\t}\n\tif role != nil {","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/api/v1/role_service.go#L25-L61","documentation":"Thrown by ListRoles when the store query for workspace roles fails. The API wraps the store error in a CodeInternal connect error, so the caller sees a generic internal failure; the actual cause (SQL error, DB unreachable) is in the server logs.","triggerScenarios":"Calling ListRoles while store.ListRoles's SELECT over the role table (filtered by the workspace ID from context) fails — metadata DB outage, bad SQL, or corrupted role rows that fail scanning.","commonSituations":"Metadata Postgres down or migrating; schema drift after a partial migration; connection pool exhaustion under heavy load; malformed workspace data in the context.","solutions":["Check the metadata database connectivity and health (PG_URL, `psql -U bbdev bbdev`).","Inspect server logs for the underlying store.ListRoles error.","Verify the role table schema matches LATEST.sql / applied migrations.","Retry after transient DB issues resolve."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"catch (e) { if (e.code === CodeInternal) { await sleep(backoff); return retryListRoles(); } throw e; }","preventionTips":["Monitor metadata Postgres availability.","Keep schema migrations applied and consistent with the server version.","Add exponential-backoff retries for CodeInternal on read APIs."],"tags":["database","roles","internal-error","connectrpc"],"backgroundTag":"database-query-failed","analyzedSha":"1870550677fe08f0d2a78c07acd27541464eb945","analyzedAt":"2026-09-06T21:16:13.665Z","contentChangedAt":"2026-09-06T21:16:13.665Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}