router-for-me/CLIProxyAPI · error

xai device token: create request: %w

Error message

xai device token: create request: %w

What it means

http.NewRequestWithContext failed while building the token-exchange POST. This is a local, pre-network failure: the tokenEndpoint URL could not be parsed into a valid request, so the request object could not even be created.

Source

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

			}
			interval = nextInterval
			timer.Reset(interval)
		}
	}
}

// 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
	}

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Log/inspect the tokenEndpoint string passed to exchangeDeviceCode
  2. Re-run discovery and check the token_endpoint value it returns
  3. Validate the URL (url.Parse + scheme check) before starting the device flow

Example fix

// before
tokenData, err := auth.WaitForAuthorization(ctx, deviceCode)

// after
if _, uerr := url.Parse(strings.TrimSpace(deviceCode.TokenEndpoint)); uerr != nil {
    return fmt.Errorf("invalid token endpoint %q: %w", deviceCode.TokenEndpoint, uerr)
}
tokenData, err := auth.WaitForAuthorization(ctx, deviceCode)
Defensive patterns

Strategy: validation

Validate before calling

if u, err := url.Parse(strings.TrimSpace(deviceCode.TokenEndpoint)); err != nil || u.Scheme == "" || u.Host == "" {
    return fmt.Errorf("invalid xAI token endpoint: %q", deviceCode.TokenEndpoint)
}

Prevention

When it happens

Trigger: tokenEndpoint is empty, not a URL, or malformed after TrimSpace — e.g. discovery returned an unusable TokenEndpoint, or a hand-crafted endpoint string with bad scheme/control characters.

Common situations: Discovery document changed shape or was proxied and returned a relative/HTML value for token_endpoint; manual configuration override of the token endpoint with a typo; trailing newline or space characters in a stored endpoint.

Related errors


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