decolua/9router · error · Error
`Provider ${providerName} does not support device code flow`
Error message
`Provider ${providerName} does not support device code flow` What it means
requestDeviceCode(providerName, codeChallenge, options) first resolves the provider via getProvider, then asserts provider.flowType === 'device_code' before delegating to provider.requestDeviceCode. If the provider exists but uses a different flow (e.g. authorization_code_pkce), it cannot initiate a device-code session, so this error is thrown instead of calling an undefined/incorrect method.
Source
Thrown at src/lib/oauth/providers/index.js:144
: provider.config;
const tokens = await provider.exchangeToken(config, code, redirectUri, codeVerifier, state, meta || {});
let extra = null;
if (provider.postExchange) {
extra = await provider.postExchange(tokens);
}
return provider.mapTokens(tokens, extra);
}
/**
* Request device code (for device_code flow)
*/
export async function requestDeviceCode(providerName, codeChallenge, options) {
const provider = getProvider(providerName);
if (provider.flowType !== "device_code") {
throw new Error(`Provider ${providerName} does not support device code flow`);
}
return await provider.requestDeviceCode(provider.config, codeChallenge, options || {});
}
/**
* Poll for token (for device_code flow)
* @param {string} providerName - Provider name
* @param {string} deviceCode - Device code from requestDeviceCode
* @param {string} codeVerifier - PKCE code verifier (optional for some providers)
* @param {object} extraData - Extra data from device code response (e.g. clientId/clientSecret for Kiro)
*/
export async function pollForToken(providerName, deviceCode, codeVerifier, extraData) {
const provider = getProvider(providerName);
if (provider.flowType !== "device_code") {
throw new Error(`Provider ${providerName} does not support device code flow`);
}
const result = await provider.pollToken(provider.config, deviceCode, codeVerifier, extraData);View on GitHub (pinned to 90b52e06ff)
Solutions
- Check provider.flowType (via getProvider(name).flowType) before choosing the flow; only call requestDeviceCode when it equals 'device_code'
- For flowType 'authorization_code_pkce' (or default), use generateAuthData(providerName, redirectUri, meta) to get authUrl/state/codeVerifier and complete the browser + callback/exchangeTokens flow instead
- If the provider should genuinely support device code, verify you are targeting the right provider name (e.g. kilocode, kiro) rather than a PKCE-only one
- Update calling code/UI to branch on flowType rather than hardcoding the device-code path
Example fix
// before
const dc = await requestDeviceCode('claude', codeChallenge); // throws: claude is not device_code
// after
import { getProvider, requestDeviceCode, generateAuthData } from '@/lib/oauth/providers/index.js';
const p = getProvider('claude');
const auth = p.flowType === 'device_code'
? await requestDeviceCode('claude', codeChallenge)
: await generateAuthData('claude', redirectUri); // use auth.authUrl in browser flow Defensive patterns
Strategy: type-guard
Validate before calling
import { getProvider } from '@/lib/oauth/providers/index.js';
function supportsDeviceCode(name) {
try { return getProvider(name).flowType === 'device_code'; } catch { return false; }
}
// if (!supportsDeviceCode(name)) use generateAuthData() browser flow instead Type guard
function isDeviceCodeProvider(name) {
const p = getProvider(name);
return p != null && p.flowType === 'device_code' && typeof p.requestDeviceCode === 'function';
} Try / catch
try {
const dc = await requestDeviceCode(name, challenge);
} catch (e) {
if (e.message.includes('does not support device code flow')) {
const auth = await generateAuthData(name, redirectUri);
// redirect user to auth.authUrl instead
return;
}
throw e;
} Prevention
- Branch OAuth UI/logic on provider.flowType, never on a hardcoded provider list
- Check flowType before calling requestDeviceCode/pollForToken anywhere in a shared client
- Remember only device_code providers (kilocode, kiro, github, etc.) support these APIs
- Write a small helper exposing flow capabilities instead of duplicating getProvider calls
When it happens
Trigger: Calling requestDeviceCode for a provider whose module sets flowType to 'authorization_code_pkce' or another non-device flow — e.g. requestDeviceCode('claude', challenge) or requestDeviceCode('github', challenge), where the correct entry point is generateAuthData + the browser auth URL flow instead.
Common situations: A generic OAuth client that always uses the device-code path regardless of provider; UI or CLI offering 'sign in with device code' for every provider; provider migrations that changed flowType; confusing providers with similar names (kilocode is device_code, but most others are not).
Related errors
- "Too many pending authorization requests. Please try again l
- `Device auth initiation failed: ${error}`
- `Device code request failed: ${error}`
- `Client registration failed: ${error}`
- `Device authorization failed: ${error}`
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/f0115e5006ed3c1a.
Report an issue: GitHub.