Chrome native messaging app-server does not inherit NO_PROXY for custom base_url

Open 💬 0 comments Opened Jul 21, 2026 by fancyboi999-bot

What version of the Codex App are you using (From "About Codex" dialog)?

Codex App 26.715.52143 (build 5591), bundled codex-cli 0.145.0-alpha.18.

Chrome extension side panel client: 1.2.27221.15725.

What subscription do you have?

API key with a custom OpenAI-compatible provider.

What platform is your computer?

Darwin 25.5.0 arm64 arm

What issue are you seeing?

The Codex Chrome extension side panel cannot send model requests when a custom base_url must bypass a macOS system proxy. The Codex App works with the same config, auth, model, gateway, and bundled CLI binary.

The side panel retries five times and then reports:

stream disconnected before completion: error sending request for url
(https://gateway.example.internal/responses)

The Chrome native messaging host starts a separate app-server executable at:

$HOME/.codex/plugins/.plugin-appserver/codex

That process does not receive NO_PROXY or no_proxy, even though the desktop Codex process receives them. The two executables have the same version, size, and SHA-256 hash.

This is not a server-side Responses API or SSE compatibility failure: the desktop app-server receives 200 OK with content-type: text/event-stream from the same endpoint while the Chrome app-server fails before receiving HTTP response headers.

What steps can reproduce the bug?

  1. On macOS, enable a loopback system proxy such as 127.0.0.1:<port>.
  2. Configure an OpenAI-compatible provider with a custom base_url, for example https://gateway.example.internal.
  3. Configure gateway.example.internal to bypass the proxy in the shell and macOS system proxy exceptions.
  4. Confirm that Codex App or the bundled CLI can send a prompt successfully.
  5. Open the ChatGPT/Codex Chrome extension side panel and send the same prompt.
  6. Observe five reconnect attempts followed by error sending request for url.
  7. Inspect the Chrome app-server environment. NO_PROXY and no_proxy are absent.

I also reproduced this outside the UI using the exact plugin app-server binary and the same CODEX_HOME:

minimal native-host-like environment
  -> five reconnects, request fails

same environment plus only:
  NO_PROXY=.example.internal
  no_proxy=.example.internal
  -> request succeeds and returns the expected model response

No proxy URL or API credential needs to be added for the successful control case. Adding only the bypass variables changes the result.

What is the expected behavior?

The Chrome native messaging host should give its app-server child the same effective outbound proxy bypass policy as Codex App.

This should not require inheriting the complete desktop or shell environment. A narrow allowlist for standard proxy variables (HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, NO_PROXY, and lowercase variants), or a first-class Codex network configuration passed to the child, would avoid exposing unrelated environment variables and credentials.

Additional information

A local workaround confirms the process-boundary diagnosis:

  1. Point the Chrome Native Messaging manifest at a wrapper.
  2. Export only NO_PROXY and no_proxy in the wrapper.
  3. exec the original signed native host.
  4. Restart the native host and plugin app-server.

The newly spawned plugin app-server then receives the bypass variables and the side panel works. This workaround is update-fragile because reinstalling or updating the Chrome plugin can rewrite the native messaging manifest.

Related but distinct reports:

  • #6764: VS Code extension does not pass NO_PROXY to the CLI. This is the closest matching mechanism, but a different host surface.
  • #21713: Codex Desktop Node REPL does not inherit proxy variables. The failing process here is the Chrome native messaging app-server handling model /responses, not Node REPL ambient fetch.
  • #13682: Codex App GUI and bundled CLI choose different routes under Clash Verge/system proxy.
  • #23504: browser ambient requests do not consistently respect proxy settings.

All company domains, account identifiers, local usernames, absolute user paths, proxy ports, credentials, and response contents have been redacted.

View original on GitHub ↗