router-for-me/CLIProxyAPI · error

Codex live request body too large

Error message

Codex live request body too large

What it means

Raised when io.ReadAll on the upstream HTTP response body fails inside the plugin host's HTTP bridge (Do). Before returning, the bridge already recorded the error via helps.RecordAPIResponseError for observability; the returned error wraps the read failure with %w.

Source

Thrown at internal/client/codex/live/live.go:506

func (h *Handler) selectOAuth(ctx context.Context, model string, opts coreexecutor.Options) (*auth.HomeDispatchSelection, *auth.Auth, error) {
	var selection *auth.HomeDispatchSelection
	var selected *auth.Auth
	var errSelect error
	if h.authManager.HomeEnabled() {
		selection, errSelect = h.authManager.SelectHomeAuthByKind(ctx, "codex", model, auth.AuthKindOAuth, opts)
		if selection != nil {
			selected = selection.CloneAuth()
		}
	} else {
		selected, errSelect = h.authManager.SelectAuthByKind(ctx, "codex", "", auth.AuthKindOAuth, opts)
	}
	if errSelect != nil && selection != nil {
		selection.End("selection_failed")
	}
	return selection, selected, errSelect
}

var errBodyTooLarge = errors.New("Codex live request body too large")

func readBody(body io.Reader) ([]byte, error) {
	payload, errRead := readLimitedBody(body)
	if errRead != nil {
		if errors.Is(errRead, errBodyTooLarge) {
			return nil, errRead
		}
		return nil, fmt.Errorf("failed to read Codex live request: %w", errRead)
	}
	return payload, nil
}

func readLimitedBody(body io.Reader) ([]byte, error) {
	if body == nil {
		return nil, nil
	}
	payload, errRead := io.ReadAll(io.LimitReader(body, maxBodySize+1))
	if errRead != nil {

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Retry the request with idempotent methods (GET) — transient resets are the most common cause.
  2. Check whether the caller's context was cancelled; decouple long plugin HTTP reads from short request deadlines.
  3. Inspect proxy configuration (config.yaml proxy settings / NewProxyAwareHTTPClient env) if a proxy sits in the path.
  4. Verify upstream server behavior with curl to rule out truncated responses.

Example fix

// plugin side: retry transient body-read failures for idempotent GETs
resp, err := http.Do(ctx, req)
for attempt := 0; err != nil && attempt < 2 && req.Method == "GET"; attempt++ {
    time.Sleep(backoff(attempt))
    resp, err = http.Do(ctx, req)
}
Defensive patterns

Strategy: retry

Try / catch

resp, err := http.Do(ctx, req)
if err != nil {
    if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
        return err // do not retry caller cancellation
    }
    var netErr net.Error
    if errors.As(err, &netErr) && netErr.Timeout() && isIdempotent(req.Method) {
        return retryWithBackoff(ctx, func() error { _, e := http.Do(ctx, req); return e })
    }
    return err
}

Prevention

When it happens

Trigger: A plugin's host.http request succeeds at the transport level but the body read is interrupted: connection reset mid-body, context cancelled while reading, proxy dropping the stream, or a Content-Length larger than what the peer sends.

Common situations: Flaky upstream networks; aggressive timeouts on the caller's context; proxies (forwarded via NewProxyAwareHTTPClient) terminating long responses; very large streaming-ish bodies the server truncates.

Related errors


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