fix: surface actionable OAuth token exchange errors#458
Draft
posthog[bot] wants to merge 1 commit into
Draft
Conversation
Token exchange in `exchangeCodeForToken` previously bubbled raw `AxiosError` instances out of `performOAuthFlow`, whose catch only branched on `timeout` and `access_denied`. Any 400 — `invalid_grant` from an expired/already-used code, `invalid_request` from a redirect URI or PKCE mismatch — surfaced as `Authorization failed: Request failed with status code 400` with no path to recover. Wrap the axios call to extract `error` and `error_description` from the OAuth payload (RFC 6749 §5.2) and re-throw a typed `OAuthTokenExchangeError`. `performOAuthFlow` then renders a code- specific message: `invalid_grant` tells the user to re-run the wizard, the rest direct them to the issue tracker with the description text. Generated-By: PostHog Code Task-Id: 6df20624-24ad-42c1-9e75-6ce6217c0831
🧙 Wizard CIRun the Wizard CI and test your changes against wizard-workbench example apps by replying with a GitHub comment using one of the following commands: Test all apps:
Test all apps in a directory:
Test an individual app:
Show more apps
Results will be posted here when complete. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When the OAuth token exchange at
POSTHOG_OAUTH_URL/oauth/tokenreturns 400, the user seesAuthorization failed: Request failed with status code 400and the wizard aborts with no path to recover. This is the very first step ofnpx @posthog/wizard, so when it triggers it's a hard block.The catch in
performOAuthFlow(src/utils/oauth.ts) only branched on'timeout'and'access_denied'substrings. Any 400 from the token endpoint —invalid_grant(expired/already-used code), PKCEcode_verifiermismatch,redirect_urimismatch — fell through to the generic message and dropped the OAuth payload on the floor. The 401 UX added in #432 didn't cover 400.Surfaced by error tracking issue
ffce0351…, first seen 2026-05-19 (currently 1 user / 1 occurrence over 30 days but P2 because it blocks the install entirely).Changes
OAuthTokenExchangeErrorinsrc/utils/oauth.tsthat carries the OAutherrorcode,error_description, and HTTP status (RFC 6749 §5.2).exchangeCodeForTokenwraps theaxios.postand, onaxios.isAxiosError, extractsresponse.data.error/error_descriptionand throws the typed error instead of letting the rawAxiosErrorescape.performOAuthFlow's catch now branches onOAuthTokenExchangeErrorfirst and renders a code-specific message viadescribeOAuthTokenExchangeError:invalid_grant→ "the authorization code was rejected... Please re-run the wizard to start a fresh login"invalid_request/invalid_client/unauthorized_client/unsupported_grant_type/invalid_scope→ labeled message +error_description+ issue-tracker link so a user filing a bug includes the diagnostic detail)" with descriptionoauth_errorandoauth_statuson captured exceptions for these failures, so similar reports are easier to group.The typed check runs before the existing
timeout/access_deniedsubstring checks so a 400 whose description happens to contain those words doesn't get mis-routed.Test plan
pnpm build— passespnpm test— 611 passed, 0 failed (the earlier flakyprovision-clitimeout cleared on re-run; unrelated to this change)pnpm lint— 0 errorsLLM context
Co-authored by PostHog Code in response to error tracking issue
ffce0351…(first occurrence 2026-05-19). Investigation traced the AxiosError throughperformOAuthFlow→askForWizardLogin→getOrAskForProjectData.Created with PostHog Code