{"record":{"id":"2760ccabfd94e8fb","repo":"decolua/9router","slug":"provider-provider-uses-device-code-login-but-i","errorCode":null,"errorMessage":"`Provider ${provider} uses device-code login but is not wired in the OAuth modal device-code list`","messagePattern":"`Provider (.+?) uses device-code login but is not wired in the OAuth modal device-code list`","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/shared/components/OAuthModal.js","lineNumber":363,"sourceCode":"          const proxyData = await proxyRes.json();\n          xaiProxyActive = proxyData.success;\n          xaiServerSide = !!proxyData.serverSide;\n          if (!xaiProxyActive && proxyData.reason === \"port_busy\") {\n            throw new Error(\"Port 56121 in use; close the conflicting process and retry\");\n          }\n        } catch (e) {\n          if (e?.message) throw e;\n          xaiProxyActive = false;\n        }\n      }\n\n      setAuthData({ ...data, redirectUri, codexServerSide, xaiServerSide });\n\n      // Guard: device_code providers return authUrl:null from /authorize. Never window.open(null)\n      // (browsers coerce it to the relative path \".../null\").\n      if (!data.authUrl) {\n        if (data.flowType === \"device_code\") {\n          throw new Error(\n            `Provider ${provider} uses device-code login but is not wired in the OAuth modal device-code list`\n          );\n        }\n        throw new Error(\"No authorization URL returned from OAuth provider\");\n      }\n\n      if (provider === \"codex\" && codexProxyActive) {\n        // Proxy active: callback will be handled server-side (auto-exchange) or via channels (fallback)\n        setStep(\"waiting\");\n        popupRef.current = window.open(data.authUrl, \"oauth_popup\", \"width=600,height=700\");\n        if (!popupRef.current) {\n          setStep(\"input\");\n        }\n      } else if (provider === \"xai\" && xaiProxyActive) {\n        setStep(\"waiting\");\n        popupRef.current = window.open(data.authUrl, \"oauth_popup\", \"width=600,height=700\");\n        if (!popupRef.current) {\n          setStep(\"input\");","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/shared/components/OAuthModal.js#L345-L381","documentation":"After /authorize returns, the modal checks data.authUrl. If authUrl is null but flowType is \"device_code\", it means the provider registry marks this provider as device-code based, yet the provider id is missing from the modal's hardcoded deviceCodeProviders list — so the modal took the wrong (authorization-code) code path. This is an internal wiring bug guard, surfaced to the user as an error.","triggerScenarios":"A provider added to the registry with flowType \"device_code\" (returns authUrl:null from /authorize) but not added to the deviceCodeProviders array in OAuthModal.js (github, kiro, kimi, kimi-coding, kilocode, codebuddy-cn, codebuddy-intl, qoder, grok-cli).","commonSituations":"A new device-code provider was registered in open-sse/providers/registry but the dashboard modal's hardcoded list was not updated — typically after adding a provider or upgrading versions where the registry and UI drift apart.","solutions":["Add the provider id to the deviceCodeProviders array in src/shared/components/OAuthModal.js","Verify the provider's registry entry really has flowType \"device_code\"","Update/upgrade both the gateway and dashboard so registry and UI are in sync","As a user workaround, use that provider's CLI-based login instead of the dashboard modal"],"exampleFix":"// before\nconst deviceCodeProviders = [\"github\",\"kiro\",\"kimi\",\"kimi-coding\",\"kilocode\",\"codebuddy-cn\",\"codebuddy-intl\",\"qoder\",\"grok-cli\"];\n// after\nconst deviceCodeProviders = [\"github\",\"kiro\",\"kimi\",\"kimi-coding\",\"kilocode\",\"codebuddy-cn\",\"codebuddy-intl\",\"qoder\",\"grok-cli\",\"new-device-provider\"];","handlingStrategy":"validation","validationCode":"// sync check: every registry device_code provider must be in the modal list\nconst missing = registryProviders.filter(p => p.flowType === \"device_code\" && !deviceCodeProviders.includes(p.id));\nif (missing.length) throw new Error(\"Device-code providers not wired in modal: \" + missing.map(p => p.id).join(\",\"));","typeGuard":"const isWired = (provider, list) => typeof provider === 'string' && list.includes(provider);","tryCatchPattern":"try {\n  await startOAuthFlow();\n} catch (e) {\n  if (e.message.includes(\"not wired in the OAuth modal\")) {\n    // fall back to CLI login for this provider\n  }\n}","preventionTips":["When adding a device-code provider, update both the registry and the modal's deviceCodeProviders list","Derive the list from the registry/config instead of hardcoding","Run the provider baseline verification scripts after registry changes"],"tags":["oauth","device-code","wiring-bug","configuration"],"backgroundTag":"provider-not-wired-in-ui","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}