vxcontrol/pentagi · error

no verified primary email found

Error message

no verified primary email found

What it means

githubEmailResolver (backend/pkg/server/oauth/github.go:56) fetches the authenticated user's emails from the GitHub API and only succeeds when at least one email has Verified=true. If none is verified, the OAuth login flow aborts with this error because the platform requires a confirmed email address to identify the account.

Source

Thrown at backend/pkg/server/oauth/github.go:56

	emails := []githubEmail{}
	if err := json.Unmarshal(body, &emails); err != nil {
		return "", false, err
	}

	for _, email := range emails {
		if email.Verified && email.Primary {
			return email.Email, true, nil
		}
	}

	for _, email := range emails {
		if email.Verified {
			return email.Email, true, nil
		}
	}

	return "", false, fmt.Errorf("no verified primary email found")
}

func NewGithubOAuthClient(clientID, clientSecret, redirectURL string) OAuthClient {
	return NewOAuthClient("github", &oauth2.Config{
		ClientID:     clientID,
		ClientSecret: clientSecret,
		RedirectURL:  redirectURL,
		Scopes: []string{
			"user:email",
			"openid",
		},
		Endpoint: github.Endpoint,
	}, githubEmailResolver)
}

View on GitHub (pinned to ea665308ba)

Solutions

  1. Ask the user to verify their email on GitHub (Settings → Emails) and retry the login.
  2. Confirm the OAuth app requests the user:email scope so the /user/emails endpoint returns full data.
  3. If no verified email exists, fall back to the GitHub noreply address (email.Primary) or prompt the user for an email instead of failing.
  4. Return a user-friendly message telling them which account is missing a verified email.

Example fix

// before
return "", false, fmt.Errorf("no verified primary email found")

// after
for _, email := range emails {
    if email.Primary && email.Verified {
        return email.Email, true, nil
    }
}
for _, email := range emails { // fallback: primary noreply address
    if email.Primary {
        return email.Email, false, nil
    }
}
return "", false, fmt.Errorf("no verified primary email found")
Defensive patterns

Strategy: validation

Validate before calling

req, _ := http.NewRequestWithContext(ctx, "GET", "https://api.github.com/user/emails", nil)
req.Header.Set("Authorization", "Bearer "+ghToken)
resp, err := http.DefaultClient.Do(req)
if err != nil {
    return err
}
var emails []struct {
    Email    string `json:"email"`
    Verified bool   `json:"verified"`
    Primary  bool   `json:"primary"`
}
json.NewDecoder(resp.Body).Decode(&emails)
resp.Body.Close()
hasVerified := false
for _, e := range emails {
    if e.Verified {
        hasVerified = true
    }
}
if !hasVerified {
    return fmt.Errorf("GitHub account has no verified email; verify it on github.com before signing in")
}

Try / catch

email, verified, err := githubEmailResolver(ctx, nonce, token)
if err != nil {
    if strings.Contains(err.Error(), "no verified primary email") {
        // guidance path, not a 500
        return nil, fmt.Errorf("sign-in failed: your GitHub account has no verified email; verify it at https://github.com/settings/emails and retry")
    }
    return nil, err
}

Prevention

When it happens

Trigger: Completing GitHub OAuth where the account's /user/emails endpoint returns only unverified addresses, or the token lacks access to verified emails, causing the resolver to fall through the loop and return this error.

Common situations: Users signing in with GitHub accounts that never confirmed their email address; freshly created or bot/service GitHub accounts; enterprise instances with unverified contact addresses; tokens missing the user:email scope so only limited data is visible.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/e44253286fe5a328. Report an issue: GitHub.