Wei-Shaw/sub2api · error

userinfo_failed

userinfo_failed

Error message

unsupported oauth provider

What it means

Thrown by fetchEmailOAuthProfile when the normalized provider name (trimmed, lowercased) is neither "github" nor "google" (code=userinfo_failed). The switch is exhaustive over the two supported providers; anything else is rejected before any userinfo call is made.

Source

Thrown at backend/internal/handler/auth_email_oauth.go:519

	resp, err := req.C().
		R().
		SetContext(ctx).
		SetBearerAuthToken(token.AccessToken).
		SetHeader("Accept", "application/json").
		Get(cfg.UserInfoURL)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode < 200 || resp.StatusCode >= 300 {
		return nil, fmt.Errorf("userinfo endpoint status %d: %s", resp.StatusCode, truncateLogValue(resp.String(), 1024))
	}
	switch strings.ToLower(strings.TrimSpace(provider)) {
	case "github":
		return parseGitHubOAuthProfile(ctx, cfg, token, resp.String())
	case "google":
		return parseGoogleOAuthProfile(resp.String())
	default:
		return nil, errors.New("unsupported oauth provider")
	}
}

func parseGitHubOAuthProfile(ctx context.Context, cfg config.EmailOAuthProviderConfig, token *emailOAuthTokenResponse, body string) (*emailOAuthProfile, error) {
	subject := strings.TrimSpace(gjson.Get(body, "id").String())
	if subject == "" {
		return nil, errors.New("github user id is missing")
	}
	email := ""
	emailsURL := strings.TrimSpace(cfg.EmailsURL)
	if emailsURL == "" {
		return nil, errors.New("github verified email is missing")
	}
	verifiedEmail, err := fetchGitHubPrimaryVerifiedEmail(ctx, emailsURL, token.AccessToken)
	if err != nil {
		return nil, err
	}
	email = verifiedEmail

View on GitHub (pinned to 073e92d171)

Solutions

  1. Set the provider name to exactly "github" or "google" (case-insensitive, surrounding whitespace is trimmed)
  2. If you need another IdP, use a provider that speaks the generic flow this system supports, or extend the switch in fetchEmailOAuthProfile
  3. Remove or disable the misconfigured provider entry so users cannot select it

Example fix

// before
providers:
  acme:
    name: "azure"
// after
providers:
  acme:
    name: "github"
Defensive patterns

Strategy: validation

Validate before calling

// TS: validate provider before initiating the flow
const SUPPORTED = new Set(['github', 'google']);
const p = provider.trim().toLowerCase();
if (!SUPPORTED.has(p)) throw new Error(`unsupported provider '${provider}'; supported: github, google`);

Type guard

type SupportedProvider = 'github' | 'google';
function isSupportedProvider(v: string): v is SupportedProvider {
  return ['github', 'google'].includes(v.trim().toLowerCase());
}

Prevention

When it happens

Trigger: Email OAuth login with a provider config whose name is e.g. "azure", "gitlab", or a typo like "Github " that survives trimming only if it is not one of the two exact values after lowercase/trim.

Common situations: Adding a new OIDC provider expecting generic support; copy-paste config errors; renaming an existing provider entry.

Related errors


AI-assisted analysis of Wei-Shaw/sub2api@073e92d171 (2026-08-15). Data as JSON: /api/errors/5bedd6590136d761. Report an issue: GitHub.