router-for-me/CLIProxyAPI · error

xai device token request failed: %w

Error message

xai device token request failed: %w

What it means

The HTTP round trip for the token exchange failed at the transport level (a.httpClient.Do error). The request was built fine but never completed: DNS failure, connection refused/reset, TLS error, or the bound context being cancelled mid-request.

Source

Thrown at internal/auth/xai/xai.go:273

// exchangeDeviceCode attempts to exchange a device code for tokens.
// Returns (token, error, nextInterval, shouldContinue).
func (a *XAIAuth) exchangeDeviceCode(ctx context.Context, tokenEndpoint, deviceCode string, interval time.Duration) (*TokenData, error, time.Duration, bool) {
	form := url.Values{
		"grant_type":  {DeviceCodeGrantType},
		"device_code": {strings.TrimSpace(deviceCode)},
		"client_id":   {ClientID},
	}

	req, err := http.NewRequestWithContext(ctx, http.MethodPost, strings.TrimSpace(tokenEndpoint), strings.NewReader(form.Encode()))
	if err != nil {
		return nil, fmt.Errorf("xai device token: create request: %w", err), interval, false
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Set("Accept", "application/json")

	resp, err := a.httpClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("xai device token request failed: %w", err), interval, false
	}
	defer func() {
		if errClose := resp.Body.Close(); errClose != nil {
			log.Errorf("xai device token: close response body error: %v", errClose)
		}
	}()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("xai device token: read response: %w", err), interval, false
	}

	var payload struct {
		Error            string `json:"error"`
		ErrorDescription string `json:"error_description"`
		AccessToken      string `json:"access_token"`
		RefreshToken     string `json:"refresh_token"`
		IDToken          string `json:"id_token"`

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Retry the flow with a fresh device code — transient network errors are common during polling
  2. Check connectivity to the token endpoint host (curl, DNS lookup) from the same environment
  3. Configure the httpClient used by XAIAuth with proxy settings or a custom CA bundle if behind a proxy
  4. Ensure the ctx passed in is not already cancelled
Defensive patterns

Strategy: retry

Try / catch

tokenData, err := auth.WaitForAuthorization(ctx, deviceCode)
if err != nil {
    var netErr net.Error
    if errors.As(err, &netErr) || strings.Contains(err.Error(), "device token request failed") {
        // transient transport failure: restart flow with backoff
        time.Sleep(backoff)
        return restartDeviceFlow(ctx)
    }
    return err
}

Prevention

When it happens

Trigger: POST to the token endpoint failing at network level: no route to host, DNS resolution failure for the xAI auth domain, TLS handshake error, proxy blocking the request, or ctx cancellation during Do.

Common situations: Corporate proxy/firewall blocking the auth domain; DNS outage; self-signed MITM proxy not in the trust store; transient network blips during a long poll loop.

Related errors


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/f330d025487e5c51. Report an issue: GitHub.