router-for-me/CLIProxyAPI · error
xai device code: response is nil
Error message
xai device code: response is nil
What it means
PollForToken was called with a nil *DeviceCodeResponse. This is a programming-contract violation, not a server condition: the poll loop needs deviceCode.DeviceCode and deviceCode.TokenEndpoint, so it fails fast instead of panicking on a nil dereference.
Source
Thrown at internal/auth/xai/xai.go:199
if err != nil {
return nil, err
}
tokenEndpoint := ""
if deviceCode != nil {
tokenEndpoint = strings.TrimSpace(deviceCode.TokenEndpoint)
}
return &AuthBundle{
TokenData: *tokenData,
LastRefresh: time.Now().UTC().Format(time.RFC3339),
BaseURL: DefaultAPIBaseURL,
TokenEndpoint: tokenEndpoint,
}, nil
}
// PollForToken polls the token endpoint until the user authorizes or the device code expires.
func (a *XAIAuth) PollForToken(ctx context.Context, deviceCode *DeviceCodeResponse) (*TokenData, error) {
if deviceCode == nil {
return nil, fmt.Errorf("xai device code: response is nil")
}
if ctx == nil {
ctx = context.Background()
}
tokenEndpoint := strings.TrimSpace(deviceCode.TokenEndpoint)
if tokenEndpoint == "" {
discovery, errDiscover := a.Discover(ctx)
if errDiscover != nil {
return nil, errDiscover
}
tokenEndpoint = discovery.TokenEndpoint
}
interval := time.Duration(deviceCode.Interval) * time.Second
if interval < defaultPollInterval {
interval = defaultPollInterval
}View on GitHub (pinned to 78f0c4079e)
Solutions
- Audit the call site: ensure RequestDeviceCode's error is checked before using its result (idiomatic `if err != nil { return err }` before PollForToken)
- Initialize the pointer only on success paths and never share nilable states across goroutines
- Keep using WaitForAuthorization, which chains RequestDeviceCode and PollForToken safely
Example fix
// before
deviceCode, _ := auth.RequestDeviceCode(ctx)
auth.PollForToken(ctx, deviceCode) // panics guard: nil
// after
deviceCode, err := auth.RequestDeviceCode(ctx)
if err != nil {
return err
}
auth.PollForToken(ctx, deviceCode) Defensive patterns
Strategy: validation
Validate before calling
deviceCode, err := auth.RequestDeviceCode(ctx)
if err != nil {
return err
}
if deviceCode == nil {
return fmt.Errorf("device code response unexpectedly nil")
} Prevention
- Always check the error from RequestDeviceCode before using its result
- Prefer WaitForAuthorization, which chains request+poll correctly
When it happens
Trigger: Calling XAIAuth.PollForToken(ctx, nil) directly, or a caller passing a nil pointer returned from a failed RequestDeviceCode whose error was ignored.
Common situations: Caller ignores the error from RequestDeviceCode and passes the resulting nil bundle onward; refactor that made DeviceCodeResponse optional without updating this path; race where the device code is cleared before polling starts.
Related errors
- xai device code: response missing device_code
- xai device code: response missing user_code
- xai device code: response missing verification URI
- xai device code: context cancelled: %w
- xai device token: create request: %w
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/1ad7c65f255f5014.
Report an issue: GitHub.