{"record":{"id":"ca61620217924b4f","repo":"decolua/9router","slug":"no-authorization-code-received-ca6162","errorCode":null,"errorMessage":"No authorization code received","messagePattern":"No authorization code received","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/lib/oauth/services/iflow.js","lineNumber":176,"sourceCode":"        }, 300000);\n\n        const checkInterval = setInterval(() => {\n          if (callbackParams) {\n            clearInterval(checkInterval);\n            clearTimeout(timeout);\n            resolve();\n          }\n        }, 100);\n      });\n\n      close();\n\n      if (callbackParams.error) {\n        throw new Error(callbackParams.error_description || callbackParams.error);\n      }\n\n      if (!callbackParams.code) {\n        throw new Error(\"No authorization code received\");\n      }\n\n      spinner.start(\"Exchanging code for tokens...\");\n\n      // Exchange code for tokens\n      const tokens = await this.exchangeCode(callbackParams.code, redirectUri);\n\n      spinner.text = \"Fetching user info...\";\n\n      // Get user info (includes API key)\n      const userInfo = await this.getUserInfo(tokens.access_token);\n\n      spinner.text = \"Saving tokens to server...\";\n\n      // Save tokens to server\n      await this.saveTokens(tokens, userInfo);\n\n      spinner.succeed(`iFlow connected successfully! (${userInfo.email || userInfo.phone})`);","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/lib/oauth/services/iflow.js#L158-L194","documentation":"Thrown by IFlowService.connect() when the OAuth callback arrives but contains no `code` query parameter (and no `error` either). Per the authorization-code flow, iFlow must return ?code=...; its absence means the redirect was malformed or a non-standard response reached the local server. Without the code, the token exchange cannot proceed.","triggerScenarios":"The callback URL is hit with unexpected query params (e.g. only `state`, a `token`, or empty params) — caused by iFlow changing its redirect shape, the user manually editing the URL, a redirect to the bare callback path, or a browser extension stripping query strings.","commonSituations":"iFlow API/flow change altering callback parameters; user copy-pasting only part of the callback URL; local server receiving a favicon or health request interpreted as the callback; browser prefetch hitting the callback before the real redirect.","solutions":["Re-run connect() and complete the browser login fully without manually editing the URL.","Inspect what query params actually arrived (add a console.log in the callback handler) to spot flow changes.","Check for iFlow API changes — if it now returns a token directly (implicit flow), update the handler.","Disable browser extensions/ad-blockers that might strip query parameters.","Verify the redirectUri used in buildAuthUrl matches the registered redirect for the client."],"exampleFix":"// before\nif (!callbackParams.code) {\n  throw new Error(\"No authorization code received\");\n}\n// after\nif (!callbackParams.code) {\n  throw new Error(`No authorization code received. Callback params: ${JSON.stringify(callbackParams)}`);\n}","handlingStrategy":"validation","validationCode":"// Validate callback params before using them\nfunction hasAuthCode(params) {\n  return params != null && typeof params === \"object\" && typeof params.code === \"string\" && params.code.length > 0;\n}\nif (!hasAuthCode(callbackParams)) throw new Error(\"Callback missing ?code= — restart the OAuth flow\");","typeGuard":"function isCallbackWithCode(p) {\n  return typeof p === \"object\" && p !== null && \"code\" in p && typeof p.code === \"string\";\n}","tryCatchPattern":"try {\n  await iflowService.connect();\n} catch (err) {\n  if (err.message === \"No authorization code received\") {\n    console.error(\"Callback arrived without ?code= — close stale tabs and retry the login.\");\n  } else { throw err; }\n}","preventionTips":["Always use the freshly opened browser tab; don't reuse or edit old callback URLs.","Close previous auth tabs before starting a new flow to avoid crossed callbacks.","Watch for iFlow flow changes (implicit/token-based redirects) and update the handler.","Disable query-stripping browser extensions when doing CLI OAuth logins."],"tags":["oauth","authorization-code","callback"],"backgroundTag":"missing-oauth-authorization-code","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}