{"record":{"id":"5bedd6590136d761","repo":"Wei-Shaw/sub2api","slug":"userinfo-failed","errorCode":"userinfo_failed","errorMessage":"unsupported oauth provider","messagePattern":"unsupported oauth provider","errorType":"http","errorClass":null,"httpStatus":302,"severity":"error","filePath":"backend/internal/handler/auth_email_oauth.go","lineNumber":519,"sourceCode":"\tresp, err := req.C().\n\t\tR().\n\t\tSetContext(ctx).\n\t\tSetBearerAuthToken(token.AccessToken).\n\t\tSetHeader(\"Accept\", \"application/json\").\n\t\tGet(cfg.UserInfoURL)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif resp.StatusCode < 200 || resp.StatusCode >= 300 {\n\t\treturn nil, fmt.Errorf(\"userinfo endpoint status %d: %s\", resp.StatusCode, truncateLogValue(resp.String(), 1024))\n\t}\n\tswitch strings.ToLower(strings.TrimSpace(provider)) {\n\tcase \"github\":\n\t\treturn parseGitHubOAuthProfile(ctx, cfg, token, resp.String())\n\tcase \"google\":\n\t\treturn parseGoogleOAuthProfile(resp.String())\n\tdefault:\n\t\treturn nil, errors.New(\"unsupported oauth provider\")\n\t}\n}\n\nfunc parseGitHubOAuthProfile(ctx context.Context, cfg config.EmailOAuthProviderConfig, token *emailOAuthTokenResponse, body string) (*emailOAuthProfile, error) {\n\tsubject := strings.TrimSpace(gjson.Get(body, \"id\").String())\n\tif subject == \"\" {\n\t\treturn nil, errors.New(\"github user id is missing\")\n\t}\n\temail := \"\"\n\temailsURL := strings.TrimSpace(cfg.EmailsURL)\n\tif emailsURL == \"\" {\n\t\treturn nil, errors.New(\"github verified email is missing\")\n\t}\n\tverifiedEmail, err := fetchGitHubPrimaryVerifiedEmail(ctx, emailsURL, token.AccessToken)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\temail = verifiedEmail","sourceCodeStart":501,"sourceCodeEnd":537,"githubUrl":"https://github.com/Wei-Shaw/sub2api/blob/073e92d17178a1ccdb0a27017f572f10c9c7ab62/backend/internal/handler/auth_email_oauth.go#L501-L537","documentation":"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.","triggerScenarios":"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.","commonSituations":"Adding a new OIDC provider expecting generic support; copy-paste config errors; renaming an existing provider entry.","solutions":["Set the provider name to exactly \"github\" or \"google\" (case-insensitive, surrounding whitespace is trimmed)","If you need another IdP, use a provider that speaks the generic flow this system supports, or extend the switch in fetchEmailOAuthProfile","Remove or disable the misconfigured provider entry so users cannot select it"],"exampleFix":"// before\nproviders:\n  acme:\n    name: \"azure\"\n// after\nproviders:\n  acme:\n    name: \"github\"","handlingStrategy":"validation","validationCode":"// TS: validate provider before initiating the flow\nconst SUPPORTED = new Set(['github', 'google']);\nconst p = provider.trim().toLowerCase();\nif (!SUPPORTED.has(p)) throw new Error(`unsupported provider '${provider}'; supported: github, google`);","typeGuard":"type SupportedProvider = 'github' | 'google';\nfunction isSupportedProvider(v: string): v is SupportedProvider {\n  return ['github', 'google'].includes(v.trim().toLowerCase());\n}","tryCatchPattern":null,"preventionTips":["Restrict the provider dropdown to github/google in any login UI","Validate provider names in config at startup, failing fast on typos"],"tags":["oauth","config","provider","validation"],"backgroundTag":null,"analyzedSha":"073e92d17178a1ccdb0a27017f572f10c9c7ab62","analyzedAt":"2026-08-15T14:33:00.750Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}