JuliusBrussee/caveman · error
Claude usage request failed with HTTP %d
Error message
Claude usage request failed with HTTP %d
What it means
fetchClaudeUsageJSON performs a GET against claude.ai/api/organizations/<org>/usage with a 15-second client timeout and requires a 2xx response. Any non-2xx status (401/403 expired session, 404 wrong org, 429 rate limit, 5xx) is converted into this error carrying the status code. The body is capped at 4 MiB on success.
Source
Thrown at proxy/internal/store/usage_import.go:149
return nil, fmt.Errorf("Claude usage refresh needs CAVEMAN_CLAUDE_USAGE_JSON or CAVEMAN_CLAUDE_SESSION_KEY plus CAVEMAN_CLAUDE_ORG_ID")
}
if strings.Contains(orgID, "/") || strings.Contains(orgID, "..") {
return nil, fmt.Errorf("invalid Claude organization id")
}
req, err := http.NewRequest("GET", "https://claude.ai/api/organizations/"+orgID+"/usage", nil)
if err != nil {
return nil, err
}
req.Header.Set("accept", "application/json")
req.Header.Set("cookie", "sessionKey="+sessionKey)
client := http.Client{Timeout: 15 * time.Second}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return nil, fmt.Errorf("Claude usage request failed with HTTP %d", resp.StatusCode)
}
return io.ReadAll(io.LimitReader(resp.Body, 4<<20))
}
func codexPaths(root string) ([]string, error) {
paths, _, err := codexPathsUntil(root, nil)
return paths, err
}
// codexPathsUntil preserves codexPaths' discovery contract while allowing the
// first-run behavior scan to stop a huge cold tree. Other import callers pass no
// deadline and retain their existing exhaustive walk.
func codexPathsUntil(root string, expired func() bool) ([]string, bool, error) {
var paths []string
timeBoxed := false
stopped := func() bool {
if expired == nil || !expired() {
return falseView on GitHub (pinned to 27d5a3981a)
Solutions
- Map the code: 401/403 -> re-export a fresh CAVEMAN_CLAUDE_SESSION_KEY from a logged-in browser; 404 -> fix CAVEMAN_CLAUDE_ORG_ID; 429 -> back off the refresh cadence; 5xx -> retry later.
- Prefer pinning the payload once via CAVEMAN_CLAUDE_USAGE_JSON to avoid depending on live cookie auth.
- Wrap the refresh in error handling that tolerates transient failures instead of crashing the surrounding job.
Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight is limited to config; you cannot validate a remote status locally.
// Ensure auth inputs are well-formed before the call:
if os.Getenv("CAVEMAN_CLAUDE_SESSION_KEY") == "" || os.Getenv("CAVEMAN_CLAUDE_ORG_ID") == "" {
return errors.New("claude usage credentials unset; live fetch will fail")
} Try / catch
summary, err := s.RefreshClaudeUsageFromEnv()
if err != nil && strings.Contains(err.Error(), "HTTP ") {
var code int
fmt.Sscanf(err.Error(), "Claude usage request failed with HTTP %d", &code)
switch {
case code == 401 || code == 403:
return errors.New("session key expired: re-export CAVEMAN_CLAUDE_SESSION_KEY")
case code == 429:
time.Sleep(30 * time.Second) // then one retry, not a loop
summary, err = s.RefreshClaudeUsageFromEnv()
case code >= 500:
return fmt.Errorf("claude.ai upstream issue (HTTP %d); retry later", code)
}
}
if err != nil {
return err
} Prevention
- Treat 401/403 as credential rotation events, not retries.
- Rate-limit scheduled refreshes to avoid 429.
- Keep a pinned CAVEMAN_CLAUDE_USAGE_JSON fallback for outages.
When it happens
Trigger: An expired or invalidated sessionKey cookie (401/403); a correct-format but wrong org id (404); hammering the endpoint from automation (429); claude.ai incident or auth flow change (5xx/redirect).
Common situations: The browser session was logged out or rotated since the key was exported; the org id belongs to a different account; a cron job refreshing too frequently; Anthropic changes cookie handling so the copied sessionKey no longer authenticates.
Related errors
- Claude usage refresh needs CAVEMAN_CLAUDE_USAGE_JSON or CAVE
- kms: %s request failed: %w
- registration failed: HTTP ${response.status}
- binary download failed: HTTP ${response.status}
- Claude call failed: {e.stderr}
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/4ec81a7ea6640ef1.
Report an issue: GitHub.