{"record":{"id":"b6c348d6810cb223","repo":"decolua/9router","slug":"callbackparams-error-description-callbackpara-b6c348","errorCode":null,"errorMessage":"${callbackParams.error_description || callbackParams.error}","messagePattern":"\\$\\{callbackParams\\.error_description \\|\\| callbackParams\\.error\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/lib/oauth/services/iflow.js","lineNumber":172,"sourceCode":"\n      await new Promise((resolve, reject) => {\n        const timeout = setTimeout(() => {\n          reject(new Error(\"Authentication timeout (5 minutes)\"));\n        }, 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","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/lib/oauth/services/iflow.js#L154-L190","documentation":"Thrown during IFlowService.connect() when the OAuth redirect back to the local callback server carries an `error` query parameter, meaning iFlow's authorization page refused the login instead of issuing a code. The message prefers the standard `error_description` and falls back to the bare `error` code (e.g. access_denied). This is the upstream's own OAuth error, relayed verbatim.","triggerScenarios":"The browser redirect lands on http://localhost:<port>/callback?error=...&error_description=... — the user clicked 'cancel'/'deny' on the consent screen, iFlow rejected the client_id or loginMethod, or the session/tenant on iFlow's side failed during login.","commonSituations":"User canceling the consent screen; wrong or revoked client_id in IFLOW_CONFIG; iFlow account without permission for the requested loginMethod/type extra params; network hiccup mid-login showing iFlow's own error page which then redirects with error.","solutions":["Read the message — it contains iFlow's error_description (e.g. 'user denied access').","If access_denied, simply re-run connect() and complete the consent screen without canceling.","If the error mentions client/invalid request, verify IFLOW_CONFIG.clientId and extraParams against current iFlow requirements.","Clear browser cookies for the iFlow domain and retry — stale SSO sessions can error out.","Wait and retry if iFlow reports a temporary server-side problem."],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await iflowService.connect();\n} catch (err) {\n  // The thrown message IS the upstream error_description/error code\n  if (/access_denied|cancel/i.test(err.message)) {\n    console.log(\"Login canceled — re-run connect and approve the consent screen.\");\n  } else if (/client|invalid_request/i.test(err.message)) {\n    console.error(\"iFlow rejected the client config — verify IFLOW_CONFIG clientId/extraParams.\");\n  } else { throw err; }\n}","preventionTips":["Complete the consent screen without closing or canceling the browser window.","Keep IFLOW_CONFIG (clientId, extraParams loginMethod/type) current with iFlow's requirements.","Clear stale iFlow SSO cookies if repeated authorization errors occur.","Treat the message text as the upstream OAuth error code/description — parse it for the cause."],"tags":["oauth","authorization","user-cancel"],"backgroundTag":"oauth-authorization-error","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}