router-for-me/CLIProxyAPI · error

kimi: failed to read refresh response: %w

Error message

kimi: failed to read refresh response: %w

What it means

Reading the refresh response body failed mid-stream after response headers arrived (io.ReadAll error on POST /api/oauth/token with grant_type=refresh_token). Transport-level interruption, not an OAuth decision — the status line was received but the payload was cut off.

Source

Thrown at internal/auth/kimi/kimi.go:397

	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Set("Accept", "application/json")
	for k, v := range c.commonHeaders() {
		req.Header.Set(k, v)
	}

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

	bodyBytes, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("kimi: failed to read refresh response: %w", err)
	}

	if resp.StatusCode == http.StatusUnauthorized || resp.StatusCode == http.StatusForbidden {
		return nil, fmt.Errorf("kimi: refresh token rejected (status %d)", resp.StatusCode)
	}

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("kimi: refresh failed with status %d: %s", resp.StatusCode, string(bodyBytes))
	}

	var tokenResp struct {
		AccessToken  string  `json:"access_token"`
		RefreshToken string  `json:"refresh_token"`
		TokenType    string  `json:"token_type"`
		ExpiresIn    float64 `json:"expires_in"`
		Scope        string  `json:"scope"`
	}

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Retry the refresh — connection-reuse races clear on a new connection; singleflight dedup means just invoking RefreshToken again suffices
  2. If frequent, reduce httpClient idle-connection reuse issues by adjusting transport settings or restarting the process
  3. Check for intermediary proxies truncating long-lived connections to auth.kimi.com
Defensive patterns

Strategy: retry

Try / catch

if err != nil && strings.Contains(err.Error(), "failed to read refresh response") {
    // connection reuse race: immediate retry on fresh connection usually succeeds
    return c.RefreshToken(ctx, refreshToken)
}

Prevention

When it happens

Trigger: Connection reset or proxy stream cut during refresh response; truncated chunked transfer; idle-connection reuse race where the pooled connection is closed just as the body streams.

Common situations: Keep-alive connection reuse races under load (server closes pooled connection mid-read), proxies with aggressive stream timeouts, flaky egress.

Related errors


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