router-for-me/CLIProxyAPI · error

Codex live session field must contain valid JSON

Error message

Codex live session field must contain valid JSON

What it means

The actual round trip failed: client.Do returned an error after the request was constructed. The bridge records the error via helps.RecordAPIResponseError for telemetry, then wraps it. Cause is anything the Go http client surfaces: DNS failure, refused connections, TLS errors, context cancellation, proxy connect failures (client comes from helps.NewProxyAwareHTTPClient with the runtime config and auth).

Source

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

		if errPart != nil {
			return nil, "", "", fmt.Errorf("failed to parse Codex live multipart body: %w", errPart)
		}
		partBody, errRead := io.ReadAll(part)
		errClose := part.Close()
		if errRead != nil {
			return nil, "", "", fmt.Errorf("failed to read Codex live multipart field: %w", errRead)
		}
		if errClose != nil {
			return nil, "", "", fmt.Errorf("failed to close Codex live multipart field: %w", errClose)
		}

		switch part.FormName() {
		case "sdp":
			value := string(partBody)
			sdp = &value
		case "session":
			if !json.Valid(partBody) {
				return nil, "", "", errors.New("Codex live session field must contain valid JSON")
			}
			session = append(json.RawMessage(nil), partBody...)
			model = modelFromJSON(partBody)
		}
	}
	if sdp == nil {
		return nil, "", "", errors.New("Codex live multipart body requires an sdp field")
	}
	if model == "" {
		model = defaultLiveModel
	}

	encoded, errEncode := encodeCallRequest(*sdp, session)
	if errEncode != nil {
		return nil, "", "", errEncode
	}
	return encoded, "application/json", model, nil
}

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Inspect the wrapped error: net.Error timeouts vs tls errors vs context.Canceled point to different fixes.
  2. Verify network egress and DNS from the host process environment (not just the dev machine).
  3. Check proxy configuration (config.yaml / NewProxyAwareHTTPClient env) matches the deployment network.
  4. Retry with backoff for idempotent requests when the error is a transient timeout/reset.
  5. For TLS failures against internal endpoints, import the CA into the host's trust store.

Example fix

// plugin side: distinguish cancellation from network failure
resp, err := http.Do(ctx, req)
if err != nil {
    if ctx.Err() != nil {
        return fmt.Errorf("request context done: %w", ctx.Err())
    }
    var netErr net.Error
    if errors.As(err, &netErr) && netErr.Timeout() && req.Method == "GET" {
        // retry once with backoff
    }
    return fmt.Errorf("host http request failed: %w", err)
}
Defensive patterns

Strategy: retry

Validate before calling

u, err := url.Parse(req.URL)
if err != nil || u.Host == "" {
    return errors.New("invalid URL before network call")
}

Try / catch

resp, err := http.Do(ctx, req)
if err != nil {
    switch {
    case errors.Is(err, context.Canceled), errors.Is(err, context.DeadlineExceeded):
        return err
    case isTLSError(err):
        return fmt.Errorf("TLS/trust issue: %w", err) // fix certs, no retry
    default:
        if isIdempotent(req.Method) && attempt < maxAttempts {
            return retryWithBackoff(...) // DNS/refused/reset may be transient
        }
        return err
    }
}

Prevention

When it happens

Trigger: Unreachable host/port, DNS resolution failure, TLS certificate mismatch, context cancelled before/during dial, configured proxy unreachable, firewall dropping the connection.

Common situations: Egress-blocked containers; wrong proxy settings in config.yaml or environment; self-signed certs on internal endpoints; plugin calling internal services from a sandboxed network; deadlines set on the caller's context being too short.

Related errors


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