{"record":{"id":"91a9ca61d6c13bff","repo":"bytebase/bytebase","slug":"failed-to-find-workspace-91a9ca","errorCode":null,"errorMessage":"failed to find workspace","messagePattern":"failed to find workspace","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/component/recovery/service.go","lineNumber":412,"sourceCode":"\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 {\n\tworkspace, err := s.store.GetWorkspaceByID(ctx, workspaceID)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to find workspace\")\n\t}\n\tif workspace == nil {\n\t\treturn errors.Errorf(\"workspace %q was not found\", workspaceID)\n\t}\n\treturn nil\n}\n\nfunc emailBelongsToDomains(email string, domains []string) bool {\n\tif len(domains) == 0 {\n\t\treturn true\n\t}\n\tfor _, domain := range domains {\n\t\tif strings.HasSuffix(email, \"@\"+strings.ToLower(domain)) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}","sourceCodeStart":394,"sourceCodeEnd":430,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/component/recovery/service.go#L394-L430","documentation":"This error wraps a failure from store.GetWorkspaceByID: the workspace lookup query itself errored (as opposed to the workspace not existing). Callers like ResetUserPassword, AddUserToWorkspace, and ListRoles require a valid workspace before proceeding.","triggerScenarios":"requireWorkspace calls s.store.GetWorkspaceByID(ctx, workspaceID) and it returns err != nil — metadata database failure, timeout, or SQL error — from any of EnablePasswordSignin, GetPasswordRestriction, IsUserInWorkspace, ListRoles, AddUserToWorkspace, or ResetUserPassword.","commonSituations":"Metadata database outage or wrong PG_URL; connection pool exhaustion under load; passing an unparseable workspace ID that causes a query error rather than a clean not-found.","solutions":["Check the wrapped cause for the database error; verify metadata DB connectivity and configuration.","Retry if the error is transient (timeout, connection reset).","Validate the workspace ID format before calling the API so it fails as not-found rather than as a query error.","Confirm workspace table migrations have been applied."],"exampleFix":"// before\nworkspace, err := s.store.GetWorkspaceByID(ctx, workspaceID)\nif err != nil {\n\treturn errors.Wrap(err, \"failed to find workspace\")\n}\n// after\nif workspaceID == \"\" {\n\treturn errors.New(\"workspace id is required\")\n}\nworkspace, err := s.store.GetWorkspaceByID(ctx, workspaceID)\nif err != nil {\n\treturn errors.Wrapf(err, \"failed to find workspace %s (check metadata DB)\", workspaceID)\n}","handlingStrategy":"validation","validationCode":"if workspaceID == \"\" {\n\treturn errors.New(\"workspace id is required\")\n}\nif err := db.PingContext(ctx); err != nil {\n\treturn fmt.Errorf(\"metadata DB unreachable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"err := svc.requireWorkspace(ctx, workspaceID)\nif err != nil && strings.Contains(err.Error(), \"failed to find workspace\") {\n\t// DB-level failure: retry transient errors\n\treturn retryWithBackoff(3, time.Second, func() error { return svc.requireWorkspace(ctx, workspaceID) })\n}","preventionTips":["Validate workspace ID format and non-emptiness before API calls","Add DB health monitoring around workspace-dependent flows","Keep metadata migrations applied in all environments"],"tags":["go","database","workspace"],"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"}