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

  1. Verify the email used for the service-account login matches an existing service account
  2. Recreate the service account if it was deleted, then re-issue credentials
  3. 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

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.