router-for-me/CLIProxyAPI · error
fetch Claude OAuth %s: HTTP client is nil
Error message
fetch Claude OAuth %s: HTTP client is nil
What it means
Returned by ClaudeAuth.fetchOAuthControlPlaneJSON when the method is invoked on a nil *ClaudeAuth receiver or when the struct's httpClient field is nil. Every OAuth control-plane GET (profile at api.anthropic.com/api/oauth/profile, roles) funnels through this helper, so a broken construction path disables all of them. ClaudeAuth is expected to be built by its constructor which always sets httpClient, so in practice this indicates the struct was created as &ClaudeAuth{} or the receiver was nil at the call site.
Source
Thrown at internal/auth/claude/anthropic_auth.go:227
}
func applyClaudeOAuthAxiosHeaders(req *http.Request) {
if req == nil {
return
}
req.Header.Set("Accept", "application/json, text/plain, */*")
req.Header.Set("Content-Type", "application/json")
req.Header.Set("User-Agent", "axios/1.15.2")
req.Header.Set("Accept-Encoding", "gzip, compress, deflate, br")
req.Header.Set("Connection", "close")
req.Close = true
}
// fetchOAuthControlPlaneJSON issues an Axios-shaped OAuth control-plane GET and
// returns the decoded response body. label names the endpoint in error text.
func (o *ClaudeAuth) fetchOAuthControlPlaneJSON(ctx context.Context, endpoint, accessToken, label string) ([]byte, error) {
if o == nil || o.httpClient == nil {
return nil, fmt.Errorf("fetch Claude OAuth %s: HTTP client is nil", label)
}
accessToken = strings.TrimSpace(accessToken)
if accessToken == "" {
return nil, fmt.Errorf("fetch Claude OAuth %s: access token is empty", label)
}
req, errRequest := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
if errRequest != nil {
return nil, fmt.Errorf("create Claude OAuth %s request: %w", label, errRequest)
}
applyClaudeOAuthAxiosHeaders(req)
req.Header.Set("Authorization", "Bearer "+accessToken)
req.Header.Set("Cache-Control", "no-cache")
resp, errDo := o.httpClient.Do(req)
if errDo != nil {
return nil, fmt.Errorf("fetch Claude OAuth %s: %w", label, errDo)
}
defer func() {View on GitHub (pinned to 78f0c4079e)
Solutions
- Construct ClaudeAuth only through its constructor (NewClaudeAuth or equivalent) so httpClient is always initialized
- If a struct literal is required, set the httpClient field explicitly: &ClaudeAuth{httpClient: &http.Client{}}
- Check the label in the message ('profile' vs 'roles') to find which call path has the nil receiver
Example fix
// before
auth := &ClaudeAuth{} // httpClient is nil
profile, err := auth.FetchOAuthProfile(ctx, token)
// after
auth := NewClaudeAuth(cfg) // httpClient initialized
profile, err := auth.FetchOAuthProfile(ctx, token) Defensive patterns
Strategy: type-guard
Validate before calling
if auth == nil {
return fmt.Errorf("ClaudeAuth is nil; construct via NewClaudeAuth")
} Type guard
func claudeAuthReady(a *ClaudeAuth) bool {
return a != nil && a.httpClient != nil
} Try / catch
if !claudeAuthReady(auth) { return fmt.Errorf("auth not initialized") }
profile, err := auth.FetchOAuthProfile(ctx, token)
if err != nil && strings.Contains(err.Error(), "HTTP client is nil") {
log.Errorf("programming error: ClaudeAuth built without constructor")
} Prevention
- Always construct ClaudeAuth through its constructor so httpClient is set
- Never build ClaudeAuth via bare struct literals in tests or refactors
When it happens
Trigger: Calling FetchOAuthProfile/FetchOAuthRoles on a ClaudeAuth built via struct literal without httpClient; invoking the method through a nil *ClaudeAuth pointer (Go allows the call, the guard catches it).
Common situations: Tests constructing ClaudeAuth{} directly instead of the constructor; refactors that store the auth in an interface whose nil concrete type is then dereferenced.
Related errors
- fetch Claude OAuth %s: access token is empty
- fetch Claude OAuth %s: %w
- read Claude OAuth %s response: %w
- decode Claude OAuth gzip response: %w
- decode Claude OAuth response: unsupported content encoding %
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/4b7f6d55003ce60b.
Report an issue: GitHub.