sipeed/picoclaw · error
Invalid device code response
Error message
Invalid device code response
What it means
Thrown in startOpenAIDeviceCode (web/frontend/src/hooks/use-credentials-page.ts:251, message from i18n key credentials.errors.invalidDeviceResponse) after POST /api/oauth/login with {provider: "openai", method: "device_code"} returns 2xx but the body is missing flow_id, user_code, or verify_url. Like error 22 it is a defensive check of the backend device-code contract — the device sheet cannot be rendered without a user code and verification URL.
Source
Thrown at web/frontend/src/hooks/use-credentials-page.ts:251
},
[bumpActionToken, isActionTokenCurrent, t],
)
const startOpenAIDeviceCode = useCallback(async () => {
const actionToken = bumpActionToken()
setActiveAction("openai:device")
setError("")
try {
const resp = await loginOAuth({
provider: "openai",
method: "device_code",
})
if (!isActionTokenCurrent(actionToken)) {
return
}
if (!resp.flow_id || !resp.user_code || !resp.verify_url) {
throw new Error(t("credentials.errors.invalidDeviceResponse"))
}
const flow: OAuthFlowState = {
flow_id: resp.flow_id,
provider: "openai",
method: "device_code",
status: "pending",
user_code: resp.user_code,
verify_url: resp.verify_url,
interval: resp.interval,
expires_at: resp.expires_at,
}
setDeviceFlow(flow)
setDeviceSheetOpen(true)
setActiveFlow(flow)
setWatchFlowID(resp.flow_id)
setWatchMode("poll")View on GitHub (pinned to 49183d7e8d)
Solutions
- Configure the OpenAI OAuth client (client id/secret with device flow enabled) in the launcher backend config
- Check the network tab: inspect POST /api/oauth/login response body to see which of flow_id/user_code/verify_url is missing
- Update the launcher backend to a version whose device flow returns the full payload
- Fall back to browser-method login or API-key credentials for OpenAI while device flow is unavailable
Defensive patterns
Strategy: try-catch
Type guard
function isDeviceLoginResponse(
resp: unknown,
): resp is { flow_id: string; user_code: string; verify_url: string; interval?: number; expires_at?: string } {
if (!resp || typeof resp !== "object") return false
const r = resp as Record<string, unknown>
return (
typeof r.flow_id === "string" && r.flow_id.length > 0 &&
typeof r.user_code === "string" && r.user_code.length > 0 &&
typeof r.verify_url === "string" && r.verify_url.length > 0
)
} Try / catch
try {
const resp = await loginOAuth({ provider: "openai", method: "device_code" })
if (!isDeviceLoginResponse(resp)) {
throw new Error(t("credentials.errors.invalidDeviceResponse"))
}
} catch (err) {
setError(err instanceof Error ? err.message : t("credentials.errors.loginFailed"))
} Prevention
- Only show the device-code button when the providers endpoint marks OpenAI device flow available
- Backend: return a non-2xx with a JSON error instead of an empty 200 when device flow is unconfigured
- Cover the device login response shape in API contract tests
When it happens
Trigger: Clicking 'OpenAI device code' login when the backend has no OpenAI OAuth client configured, the backend's device-flow endpoint returned an empty/partial object, or a middlebox altered the response. Triggered when resp.flow_id, resp.user_code, or resp.verify_url is falsy.
Common situations: OpenAI provider configured with API key only (no OAuth app) so device flow returns nothing; backend version that lacks device_code support; corporate proxy mangling the JSON; provider status endpoint says available but login endpoint disagrees.
Related errors
- Invalid browser login response
- requesting device code: %w
- device code request failed: %s
- failed to request device code: %v
- ${label} must be a JSON object.
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/f6d9654a3e22333b.
Report an issue: GitHub.