Skip to content

FM-037 — OAuth Authorize 404 — Three-Layer Routing Mismatch

/oauth/authorize 404 from Forge IDE — path mismatch + dropped returnTo + PublicOnlyRoute race.

FieldValue
SeveritySEV-2 (Forge IDE OAuth flow broken)
CategoryAuth / Routing
Date2026-04-04
StatusArchived

Navigating to https://cmmd.ai/oauth/authorize?client_id=cmmd-forge&... showed a 404 instead of the OAuth authorization flow.

Three compounding bugs:

  1. Path mismatch: OAuth API endpoints live at /api/oauth/authorize but Forge IDE opens /oauth/authorize. SPA catch-all served the React app, which had no route for /oauth/* → 404.
  2. returnTo dropped: The /auth/login redirect used wouter’s <Redirect> which dropped query params.
  3. PublicOnlyRoute race: After login, PublicOnlyRoute unmounts AuthPage and redirects to /home before AuthPage’s returnTo handler fires. Additionally, wouter’s <Redirect> does client-side pushState which doesn’t hit Express for /api/* routes.
  1. Added OAuthForward route — redirects /oauth/*/api/oauth/* via window.location.replace
  2. Replaced /auth/login redirect with AuthRedirectPreserveParams
  3. Added resolveReturnTo() to PublicOnlyRoute
  4. Added FullPageRedirect component for server routes (uses window.location.replace)
  5. Changed server OAuth redirect from /auth?returnTo=... to /login?returnTo=...
  • When adding API endpoints for external clients (IDEs, mobile apps), test with the user-facing URL without /api/ prefix
  • When redirecting between SPA routes and server routes, use window.location, never wouter’s <Redirect>
  • When redirecting between public routes, preserve query params