sipeed/picoclaw · error

failed to request device code: %v

Error message

failed to request device code: %v

What it means

Returned as HTTP 500 by POST /api/oauth/login when method is "device_code" and auth.RequestDeviceCode fails. That helper POSTs JSON {"client_id": ...} to https://auth.openai.com/api/accounts/deviceauth/usercode using the OpenAI OAuth client config; failure means either the outbound HTTP request itself failed (DNS, proxy, timeout) or the endpoint returned a non-2xx status. The %v detail distinguishes "requesting device code: ..." (transport) from an HTTP status body.

Source

Thrown at web/backend/api/oauth.go:237

		}
		if err := h.persistCredentialAndConfig(provider, oauthMethodToken, cred); err != nil {
			http.Error(w, fmt.Sprintf("token login failed: %v", err), http.StatusInternalServerError)
			return
		}

		w.Header().Set("Content-Type", "application/json")
		_ = json.NewEncoder(w).Encode(map[string]any{
			"status":   "ok",
			"provider": provider,
			"method":   method,
		})
		return

	case oauthMethodDeviceCode:
		cfg := auth.OpenAIOAuthConfig()
		info, err := oauthRequestDeviceCode(cfg)
		if err != nil {
			http.Error(w, fmt.Sprintf("failed to request device code: %v", err), http.StatusInternalServerError)
			return
		}

		now := oauthNow()
		flow := &oauthFlow{
			ID:           newOAuthFlowID(),
			Provider:     provider,
			Method:       method,
			Status:       oauthFlowPending,
			CreatedAt:    now,
			UpdatedAt:    now,
			ExpiresAt:    now.Add(oauthDeviceCodeFlowTTL),
			DeviceAuthID: info.DeviceAuthID,
			UserCode:     info.UserCode,
			VerifyURL:    info.VerifyURL,
			Interval:     info.Interval,
		}
		h.storeOAuthFlow(flow)

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Verify egress from the backend host: curl -sS -o /dev/null -w '%{http_code}' https://auth.openai.com/api/accounts/deviceauth/usercode.
  2. Set HTTPS_PROXY/HTTP_PROXY (and NO_PROXY) in the backend process environment and restart it if a proxy is required.
  3. Retry after a short wait — a 5xx from the endpoint or a transient network failure is often short-lived.
  4. Check backend logs (logger.Errorf) for the wrapped cause; TLS certificate errors point at interception, DNS errors at resolver config.
  5. If device_code cannot work in the environment, fall back to method "token" for openai, which needs no outbound call.

Example fix

# before: backend started without proxy awareness
systemctl start picoclaw-web  # 500 failed to request device code: ... dial tcp ... i/o timeout

# after
# /etc/systemd/system/picoclaw-web.service.d/proxy.conf
[Service]
Environment="HTTPS_PROXY=http://proxy.corp:3128"
Environment="NO_PROXY=localhost,127.0.0.1"
Defensive patterns

Strategy: retry

Validate before calling

await fetch('https://auth.openai.com', {method:'HEAD', signal: AbortSignal.timeout(5000)}); // preflight egress before offering device_code

Try / catch

async function requestDeviceCode(provider, attempt = 0) {
  const res = await fetch('/api/oauth/login', {method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({provider, method:'device_code'})});
  if (res.status === 500) {
    const { message } = await res.json();
    if (/device code/i.test(message ?? '') && attempt < 3) {
      await new Promise(r => setTimeout(r, 1500 * 2 ** attempt));
      return requestDeviceCode(provider, attempt + 1);
    }
    throw new Error(message);
  }
  return res.json();
}

Prevention

When it happens

Trigger: POST /api/oauth/login {"provider":"openai","method":"device_code"} while the host has no route to auth.openai.com, an HTTPS proxy is required but unset, a corporate firewall TLS-intercepts auth.openai.com, or OpenAI's device authorization endpoint returns 4xx/5xx.

Common situations: Air-gapped or egress-filtered deployment; HTTPS_PROXY/HTTP_PROXY not set in the backend's environment; OpenAI auth outage; captive portal intercepting the request; DNS failure inside a container.

Related errors


AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15). Data as JSON: /api/errors/7e004d02d61881fa. Report an issue: GitHub.