{"record":{"id":"5f7a11bcd22e21c8","repo":"dubinc/dub","slug":"not-found","errorCode":null,"errorMessage":"Not found","messagePattern":"Not found","errorType":"http","errorClass":null,"httpStatus":404,"severity":"warning","filePath":"packages/cli/src/api/callback.ts","lineNumber":27,"sourceCode":"\ninterface OAuthCallbackServerProps {\n  oauthClient: OAuth2Client;\n  redirectUri: string;\n  spinner: Ora;\n  codeVerifier: string;\n}\n\nexport function oauthCallbackServer({\n  oauthClient,\n  redirectUri,\n  codeVerifier,\n  spinner,\n}: OAuthCallbackServerProps) {\n  const server = http.createServer(async (req, res) => {\n    const reqUrl = url.parse(req.url || \"\", true);\n\n    if (reqUrl.pathname !== \"/callback\" || req.method !== \"GET\") {\n      res.writeHead(404);\n      res.end(\"Not found\");\n      return;\n    }\n\n    const code = reqUrl.query.code as string;\n\n    if (!code) {\n      res.writeHead(400);\n      res.end(\n        \"Authorization code not found. Please start the login process again.\",\n      );\n\n      return;\n    }\n\n    try {\n      spinner.text = \"Verifying\";\n","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/dubinc/dub/blob/f216b94a24ca5a0a48c6543ee10392c9006c8b75/packages/cli/src/api/callback.ts#L9-L45","documentation":"The local OAuth callback HTTP server (listening on port 4587 during `login`) responds with HTTP 404 and the plain-text body \"Not found\" for any request that is not a GET to the /callback path. This body surfaces in the browser tab that the OAuth flow opened, and is expected behavior for stray requests rather than a thrown exception.","triggerScenarios":"The browser hits http://localhost:4587/ without the /callback path, uses a non-GET method, or the OAuth provider redirects to a redirect_uri whose pathname differs from /callback (e.g. trailing slash, different path, or a host/port mismatch).","commonSituations":"Users manually opening the port in a browser, health-check scanners probing localhost, or a misconfigured redirect URI in the OAuth app registration sending the authorization code to a different pathname.","solutions":["Make sure the OAuth app's registered redirect URI is exactly http://localhost:4587/callback (matching path, no trailing slash).","Complete the flow by following the provider's redirect rather than typing the URL by hand.","If a proxy or dev tool rewrites the path, disable it for localhost:4587 during login.","Restart `login` if the browser landed on the wrong URL — a fresh flow issues a new authorization code."],"exampleFix":"// before (OAuth app settings)\nredirect_uri = http://localhost:4587/callback/\n// after\nredirect_uri = http://localhost:4587/callback","handlingStrategy":"validation","validationCode":"// Verify the redirect URI before starting the flow\nconst redirectUri = 'http://localhost:4587/callback';\nif (new URL(redirectUri).pathname !== '/callback') {\n  throw new Error('redirect_uri path must be /callback');\n}","typeGuard":"function isCallbackRequest(req: { url?: string; method?: string }): boolean {\n  const parsed = new URL(req.url || '', 'http://localhost:4587');\n  return parsed.pathname === '/callback' && req.method === 'GET';\n}","tryCatchPattern":"// Server-side: the 404 is sent as a response, not thrown. Guard the flow instead:\nif (!isCallbackRequest(req)) {\n  res.writeHead(404);\n  res.end('Not found');\n  return;\n}","preventionTips":["Register the redirect URI in the OAuth app exactly as http://localhost:4587/callback.","Never type the callback URL manually; always follow the provider's redirect.","Disable proxies/interceptors on localhost:4587 while logging in.","Check the browser's address bar if you see 'Not found' — the path is wrong."],"tags":["oauth","http-404","cli"],"backgroundTag":"oauth-redirect-uri-mismatch","analyzedSha":"f216b94a24ca5a0a48c6543ee10392c9006c8b75","analyzedAt":"2026-08-31T18:35:50.395Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}