{"record":{"id":"6a6a7eb9981894b0","repo":"Billionmail/BillionMail","slug":"failed-to-get-account-roles","errorCode":null,"errorMessage":"Failed to get account roles","messagePattern":"Failed to get account roles","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"core/internal/controller/rbac/rbac_v1_auth.go","lineNumber":91,"sourceCode":"\t\tif !service.VerifyCaptcha(req.ValidateCodeId, req.ValidateCode) {\n\t\t\terr = fmt.Errorf(\"Invalid validation code\")\n\t\t\treturn\n\t\t}\n\n\t\tvalidateSuccess = true\n\t}\n\n\t// Verify username and password\n\taccount, err := service.Account().Login(ctx, req.Username, req.Password)\n\tif err != nil {\n\t\terr = fmt.Errorf(\"Invalid username or password\")\n\t\treturn\n\t}\n\n\t// Get account roles\n\troles, err := service.Account().GetAccountRoles(ctx, account.AccountId)\n\tif err != nil {\n\t\terr = fmt.Errorf(\"Failed to get account roles\")\n\t\treturn\n\t}\n\n\t// Convert roles to role names\n\troleNames := make([]string, 0, len(roles))\n\tfor _, role := range roles {\n\t\troleNames = append(roleNames, role.RoleName)\n\t}\n\n\t// Generate JWT token\n\ttoken, _, err := service.JWT().GenerateToken(account.AccountId, account.Username, roleNames)\n\tif err != nil {\n\t\tres.SetError(gerror.New(\"Failed to generate token\"))\n\t\treturn\n\t}\n\n\t// Generate refresh token\n\trefreshToken, err := service.JWT().GenerateRefreshToken(account.AccountId, account.Username)","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/controller/rbac/rbac_v1_auth.go#L73-L109","documentation":"This error is returned by the login endpoint after the username/password check succeeded, but fetching the account's assigned roles from the database failed. The underlying DB error is intentionally swallowed and replaced with a generic message, so the root cause (DB down, missing role tables, bad connection) is hidden. Login cannot proceed because roles are required to build the JWT claims.","triggerScenarios":"POST /rbac login when service.Account().GetAccountRoles(ctx, accountId) returns an error: PostgreSQL unreachable/down, database schema missing or corrupted (account_role/role tables dropped), or the account was deleted between the Login check and the role query.","commonSituations":"Database container not started or crashed in a docker-compose deployment; running the app against an uninitialized DB without migrations; connection pool exhaustion under load; schema drift after an upgrade.","solutions":["Verify PostgreSQL is reachable and the database is initialized (docker compose ps, check core config db settings)","Run any migration/SQL setup scripts to recreate the role tables if schema is missing","Check app logs for the original DB error suppressed by this wrapper","Restart the service after restoring DB connectivity"],"exampleFix":"// before\nroles, err := service.Account().GetAccountRoles(ctx, account.AccountId)\nif err != nil {\n    err = fmt.Errorf(\"Failed to get account roles\")\n    return\n}\n// after\nroles, err := service.Account().GetAccountRoles(ctx, account.AccountId)\nif err != nil {\n    err = fmt.Errorf(\"Failed to get account roles: %w\", err)\n    return\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const res = await api.login(username, password);\n} catch (e) {\n  if (e.message.includes('Failed to get account roles')) {\n    // server-side DB issue; alert ops, do not retry credentials\n    showMaintenanceNotice();\n  }\n}","preventionTips":["Ensure the database is up and migrated before allowing logins","Wrap GetAccountRoles errors with %w so root causes are visible in logs","Monitor DB connectivity with healthchecks","Avoid deleting accounts mid-request"],"tags":["database","auth","login","roles"],"backgroundTag":"database-unavailable","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}