bytebase/bytebase · error

failed to get id by email

Error message

failed to get id by email

What it means

The Microsoft Graph lookup that maps user emails to Teams user IDs failed inside postDirectMessage, wrapped as 'failed to get id by email'. p.getIDByEmail authenticates against Microsoft Graph (tenant/client id/secret from the Teams IM setting) and queries users by email; any Graph API, auth, or network failure here is surfaced under this message. When this fails, direct @-mentions cannot be delivered and Post falls back to the channel webhook.

Source

Thrown at backend/plugin/webhook/teams/teams.go:173

	p := newProvider(teams.TenantId, teams.ClientId, teams.ClientSecret)
	ctx := context.Background()

	sent := map[string]bool{}

	if err := common.Retry(ctx, func() error {
		var errs error

		var emails []string
		for _, u := range webhookCtx.MentionEndUsers {
			if sent[u.Email] {
				continue
			}
			emails = append(emails, u.Email)
		}

		idByEmail, err := p.getIDByEmail(ctx, emails)
		if err != nil {
			return errors.Wrapf(err, "failed to get id by email")
		}

		for _, u := range webhookCtx.MentionEndUsers {
			if sent[u.Email] {
				continue
			}
			id, ok := idByEmail[u.Email]
			if !ok {
				continue
			}

			err := p.sendMessage(ctx, id, getAdaptiveCard(webhookCtx))
			if err != nil {
				slog.Error("Teams failed to send message",
					slog.String("email", u.Email),
					log.BBError(err))
				err = errors.Wrapf(err, "failed to send message to %s", u.Email)
				multierr.AppendInto(&errs, err)

View on GitHub (pinned to 1870550677)

Solutions

  1. Check the wrapped cause: if 401/invalid_client, rotate the client secret in Azure AD app registration and update Bytebase Teams settings.
  2. Grant the app the required Graph application permissions (e.g. User.Read.All) and admin consent them.
  3. Verify tenant ID, client ID, and client secret in the Teams IM setting are correct.
  4. Confirm mentioned users' emails match their Azure AD sign-in addresses (UPNs).
  5. If Graph is transiently failing, rely on the existing retry or re-trigger the event; the channel webhook fallback still delivers the notification.

Example fix

// before (assuming permission exists)
idByEmail, err := p.getIDByEmail(ctx, emails)
// after (pre-validate creds and log cause)
if err := p.pingGraphAuth(ctx); err != nil {
  return errors.Wrapf(err, "teams graph auth invalid: check tenantId/clientId/secret and admin consent")
}
idByEmail, err := p.getIDByEmail(ctx, emails)
if err != nil { return errors.Wrapf(err, "failed to get id by email") }
Defensive patterns

Strategy: fallback

Validate before calling

// preflight the Teams IM setting before enabling direct messages
if tenantID == "" || clientID == "" || clientSecret == "" { return errors.New("teams direct message requires tenantId, clientId and clientSecret") }
_, err := p.getIDByEmail(ctx, []string{testUserEmail}) // dry-run one lookup

Try / catch

delivered := postDirectMessage(ctx) // returns false on any failure
if !delivered {
    log.Warn("teams direct message failed; channel webhook fallback used")
    // Post() already falls back to the channel webhook — monitor logs for root cause
}

Prevention

When it happens

Trigger: Receiver.Post with DirectMessage=true and MentionEndUsers set; getTeamsConfig returns a Teams setting, then common.Retry -> p.getIDByEmail(ctx, emails) errors — expired/invalid client secret, Graph API 401/403, network failure, or a user principal not found/ambiguous in the tenant.

Common situations: Client secret expired in Azure AD app registration; app lacks User.Read.All (or equivalent) application permission with admin consent; tenant ID or client ID typo'd in Bytebase IM settings; user left the tenant so email no longer resolves; transient Graph API outages (retry is already applied via common.Retry).

Related errors


AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06). Data as JSON: /api/errors/cf99e766d9e2a755. Report an issue: GitHub.