bytebase/bytebase · error
service account %q not found
Error message
service account %q not found
What it means
resolveWorkspaceForLogin could not locate a SERVICE account row for the given email. Service accounts carry their own workspace field, so when none exists for the email the resolver cannot continue and returns this error, which callers surface as a login failure.
Source
Thrown at backend/api/v1/auth_service.go:865
// For END_USER: resolution order:
// 1. preferredWorkspaceID (from the login request's ?workspace= hint, e.g. invite links)
// 2. Last login workspace (from user profile)
// 3. First workspace from IAM membership
//
// Each candidate is validated for membership before use.
func (s *AuthService) resolveWorkspaceForLogin(ctx context.Context, user *store.UserMessage, preferredWorkspaceID string) (string, error) {
// Determine member name format based on user type.
switch user.Type {
case storepb.PrincipalType_SERVICE_ACCOUNT:
// SA has workspace on its record — look it up directly.
sa, err := s.store.GetServiceAccountByEmail(ctx, user.Email)
if err != nil {
return "", errors.Wrap(err, "failed to get service account")
}
if sa != nil {
return sa.Workspace, nil
}
return "", errors.Errorf("service account %q not found", user.Email)
case storepb.PrincipalType_END_USER:
includeAllUser := !s.profile.SaaS
// Prefer the workspace from the login request hint (e.g. invite link).
if preferredWorkspaceID != "" {
ws, err := s.store.FindWorkspace(ctx, &store.FindWorkspaceMessage{
WorkspaceID: &preferredWorkspaceID,
Email: user.Email,
IncludeAllUser: includeAllUser,
})
if err != nil {
return "", errors.Wrap(err, "failed to find workspace")
}
if ws != nil {
return ws.ResourceID, nil
}
// Not a member of preferred workspace — fall through.
}View on GitHub (pinned to 1870550677)
Solutions
- Verify the email used for the service-account login matches an existing service account
- Recreate the service account if it was deleted, then re-issue credentials
- If this should be a human login, authenticate as an END_USER principal instead
Example fix
// before login(ctx, "deploy-bot@old-corp.com", token) // service account deleted // after // recreate the service account or use the replacement email login(ctx, "deploy-bot@new-corp.com", token)
Defensive patterns
Strategy: validation
Validate before calling
// verify the service account exists before login
sa, _ := store.GetServiceAccount(ctx, email)
if sa == nil { return fmt.Errorf("service account %q not provisioned", email) } Try / catch
on connect error code == CodeNotFound / message contains "service account": alert ops to (re)provision the service account
Prevention
- Keep service-account emails in config synced with the workspace
- Audit service-account deletion before rotating client credentials
- Use the ID returned at account creation, not hand-typed emails
When it happens
Trigger: A Login, ResetPassword, or IDP sign-in call supplies credentials for a user whose principal type is SERVICE_ACCOUNT but no matching service account row exists in the store (e.g. the account was deleted or the email is wrong).
Common situations: Machine-to-machine logins using a stale or deleted service-account email; typo'd client credential emails; environments where service accounts were purged during migration or cleanup.
Understand the failure class
Background: "User not found", "Invalid user", and "does not exist": what missing-user lookup errors mean across Rocket.Chat, LiteLLM, Phabricator, rustfs, and pnpm — this error's family across 10 libraries.
Related errors
AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06).
Data as JSON: /api/errors/f0ff08052afd4462.
Report an issue: GitHub.