router-for-me/CLIProxyAPI · error

create upstream PeerConnection: %w

Error message

create upstream PeerConnection: %w

What it means

Thrown when the second PeerConnection (toward OpenAI's upstream) cannot be created — either the plain upstream API or, when a proxy is configured, proxyUpstreamAPI with ICEServers stripped. The downstream PeerConnection and the limiter slot are cleaned up before returning. Same pion failure classes as downstream creation, plus anything specific to the proxy-routed SettingEngine.

Source

Thrown at internal/client/codex/live/media.go:301

	releaseSlot := r.limiter.release
	downstream, errDownstream := r.downstreamAPI.NewPeerConnection(r.configuration)
	if errDownstream != nil {
		releaseSlot()
		return nil, "", fmt.Errorf("create downstream PeerConnection: %w", errDownstream)
	}
	upstreamAPI := r.upstreamAPI
	upstreamConfiguration := r.configuration
	if proxied {
		upstreamAPI = r.proxyUpstreamAPI
		upstreamConfiguration.ICEServers = nil
	}
	upstream, errUpstream := upstreamAPI.NewPeerConnection(upstreamConfiguration)
	if errUpstream != nil {
		releaseSlot()
		if errClose := downstream.Close(); errClose != nil {
			log.WithError(errClose).Debug("codex live media: close downstream PeerConnection after setup error")
		}
		return nil, "", fmt.Errorf("create upstream PeerConnection: %w", errUpstream)
	}

	session := &pionMediaSession{
		downstream:     downstream,
		upstream:       upstream,
		done:           make(chan struct{}),
		mediaSessionID: uuid.NewString(),
		releaseSlot:    releaseSlot,
		proxyDialer:    proxyDialer,
		proxyScheme:    proxyScheme(route.proxyURL),
		credential:     strings.TrimSpace(route.credential),
		authIndex:      strings.TrimSpace(route.authIndex),
	}
	session.bridge = newDataChannelBridge(session.done, func(err error) {
		session.fail("data_channel_failed", err)
	})
	session.installStateHandlers()
	log.WithFields(session.logFields("session")).Info("codex live WebRTC media session created")

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Apply the same ICE server URL/credential validation as for the downstream leg
  2. If using a proxy route, check the proxy itself is reachable and correctly configured (error 322 precedes this)
  3. Retry once for transient ICE-agent creation failures
  4. Raise max-sessions only after ruling out resource exhaustion (the limiter correctly frees the slot here)
Defensive patterns

Strategy: retry

Try / catch

if _, _, err := relay.NewSession(ctx, offer, route); err != nil {
	if strings.Contains(err.Error(), "create upstream PeerConnection") {
		// session state was cleaned up; safe to retry once
		time.Sleep(100 * time.Millisecond)
		_, _, err = relay.NewSession(ctx, offer, route)
	}
}

Prevention

When it happens

Trigger: Same as 323 but on the upstream leg; with proxied=true, failure is tied to the loopback-only proxy API configuration rather than ICE servers (they are nil'd for the proxy path).

Common situations: Malformed STUN/TURN URLs (non-proxied path), ICE agent creation failure on the loopback-only proxy API, or resource exhaustion while two PCs are being created back to back.

Related errors


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