router-for-me/CLIProxyAPI · error

models request failed with status %d: %s

Error message

models request failed with status %d: %s

What it means

fetchModels in cmd/fetch_codex_models/main.go performs GET on the Codex models endpoint and, when the HTTP status is outside 2xx, returns `models request failed with status %d: %s` including the trimmed response body. The wrapped body usually distinguishes auth failure (401/403), bad client version (400), rate limiting (429), or upstream outage (5xx).

Source

Thrown at cmd/fetch_codex_models/main.go:274

			httpClient.Transport = transport
		}
	}

	httpResp, errDo := httpClient.Do(httpReq)
	if errDo != nil {
		return nil, 0, errDo
	}

	bodyBytes, errRead := io.ReadAll(httpResp.Body)
	if errClose := httpResp.Body.Close(); errClose != nil && errRead == nil {
		errRead = errClose
	}
	if errRead != nil {
		return nil, 0, errRead
	}

	if httpResp.StatusCode < http.StatusOK || httpResp.StatusCode >= http.StatusMultipleChoices {
		return nil, 0, fmt.Errorf("models request failed with status %d: %s", httpResp.StatusCode, strings.TrimSpace(string(bodyBytes)))
	}

	count, errCount := countModels(bodyBytes)
	if errCount != nil {
		return nil, 0, errCount
	}
	return bodyBytes, count, nil
}

func codexModelsURL(clientVersion string) (string, error) {
	u, err := url.Parse(codexModelsBaseURL + codexModelsPath)
	if err != nil {
		return "", err
	}
	if strings.TrimSpace(clientVersion) != "" {
		q := u.Query()
		q.Set("client_version", strings.TrimSpace(clientVersion))
		u.RawQuery = q.Encode()

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Read the status code and embedded body in the error message: 401/403 -> fix credentials (re-login); 400 -> correct the client version; 429 -> wait and retry; 5xx -> retry later.
  2. Confirm the auth file refreshes cleanly (the tool refreshes automatically; failure surfaces as errors 45/46 first).
  3. Pass the client version of a current Codex CLI release via the flag/config the tool exposes.
  4. If behind a proxy, ensure proxy env vars reach the tool and the proxy permits chatgpt.com/backend-api endpoints.
Defensive patterns

Strategy: retry

Type guard

func isModelsHTTPStatusError(err error) bool {
    return err != nil && strings.Contains(err.Error(), "models request failed with status")
}

func modelsStatus(err error) int { /* parse the %d from the message */ }

Try / catch

body, count, err := fetchModels(ctx, auth, token, ver)
if isModelsHTTPStatusError(err) {
    switch modelsStatus(err) {
    case 401, 403: relogin()
    case 429:      time.Sleep(backoff); retry()
    default:       logAndAbort(err)
    }
}

Prevention

When it happens

Trigger: Access token expired or invalid (401); account not entitled to Codex models (403); wrong client_version query param (400); too many requests (429); upstream OpenAI endpoint error (5xx); corporate proxy returning its own error page with a non-2xx status.

Common situations: Running the fetch tool with stale credentials after failing to refresh; passing a --client-version that the endpoint no longer accepts; scripted/CI runs hammering the endpoint and hitting rate limits; region-blocked accounts.

Related errors


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