{"record":{"id":"324eb9bc6f07782a","repo":"bytebase/bytebase","slug":"failed-to-find-user-identity","errorCode":null,"errorMessage":"failed to find user identity","messagePattern":"failed to find user identity","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/component/recovery/service.go","lineNumber":391,"sourceCode":"\t// without this, the operator hands over a password that Login keeps\n\t// refusing with ResourceExhausted until the window lapses.\n\tif err := s.store.ClearLoginAttempt(ctx, email, storepb.LoginAttemptKind_PASSWORD); err != nil {\n\t\tif result.Changed {\n\t\t\treturn result, errors.Wrap(err, \"password was reset, but failed to clear the login attempt counter\")\n\t\t}\n\t\treturn result, errors.Wrap(err, \"failed to clear the login attempt counter\")\n\t}\n\n\tif err := s.createAuditLog(ctx, request.WorkspaceID, resetUserPasswordAuditMethod, string(auditRequest)); err != nil {\n\t\treturn result, errors.Wrap(err, \"user password reset completed, but failed to create the recovery audit log\")\n\t}\n\treturn result, nil\n}\n\nfunc (s *Service) getActiveEndUser(ctx context.Context, email string) (*store.UserMessage, error) {\n\taccount, err := s.store.GetAccountByEmail(ctx, email)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed to find user identity\")\n\t}\n\tif account == nil {\n\t\treturn nil, errors.Errorf(\"user %q does not exist\", email)\n\t}\n\tif account.Type != storepb.PrincipalType_END_USER || account.MemberDeleted {\n\t\treturn nil, errors.Errorf(\"user %q is not an active end user\", email)\n\t}\n\tuser, err := s.store.GetUserByEmail(ctx, email)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed to load user identity\")\n\t}\n\tif user == nil || user.MemberDeleted {\n\t\treturn nil, errors.Errorf(\"user %q is not an active end user\", email)\n\t}\n\treturn user, nil\n}\n\nfunc (s *Service) requireWorkspace(ctx context.Context, workspaceID string) error {","sourceCodeStart":373,"sourceCodeEnd":409,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/component/recovery/service.go#L373-L409","documentation":"This error wraps a failure from store.GetAccountByEmail: the account lookup itself errored (as opposed to returning no row). The library distinguishes lookup errors from 'not found' so callers know the query failed rather than the user being absent.","triggerScenarios":"getActiveEndUser calls s.store.GetAccountByEmail(ctx, email) and it returns err != nil — e.g. metadata database connectivity failure, query timeout, or SQL error — while resolving a user in AddUserToWorkspace or ResetUserPassword.","commonSituations":"Metadata database outage or misconfigured PG_URL during password recovery; transient network blips between the app and Postgres; malformed email input causing an unusual query path.","solutions":["Check the wrapped cause for the actual database error and verify the metadata database connection (PG_URL) is correct and reachable.","Retry the operation if the cause is transient (connection reset, timeout).","Confirm the account/user tables exist and migrations have run (LATEST.sql applied).","Validate the email argument is well-formed before calling the recovery APIs."],"exampleFix":"// before\naccount, err := s.store.GetAccountByEmail(ctx, email)\nif err != nil {\n\treturn nil, errors.Wrap(err, \"failed to find user identity\")\n}\n// after\nif email == \"\" {\n\treturn nil, errors.New(\"email is required\")\n}\naccount, err := s.store.GetAccountByEmail(ctx, email)\nif err != nil {\n\tif isTransientDBError(err) {\n\t\treturn nil, retry.Wrap(err)\n\t}\n\treturn nil, errors.Wrap(err, \"failed to find user identity\")\n}","handlingStrategy":"validation","validationCode":"if email == \"\" || !strings.Contains(email, \"@\") {\n\treturn errors.New(\"a valid email is required\")\n}\nif err := db.PingContext(ctx); err != nil {\n\treturn fmt.Errorf(\"metadata DB unreachable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"user, err := svc.getActiveEndUser(ctx, email)\nvar dbErr *store.DBError\nif errors.As(err, &dbErr) {\n\t// transient: retry with backoff\n\treturn retryWithBackoff(func() error { _, err = svc.getActiveEndUser(ctx, email); return err })\n}","preventionTips":["Validate email format before calling recovery APIs","Add DB health checks/retries around store lookups","Keep metadata DB migrations current"],"tags":["go","database","user-lookup"],"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-14T00:17:10.932Z"}