Skip to content

opencode attach ignores NO_PROXY — loopback requests sent through HTTP(S)_PROXY #37043

Description

@idailylife

Description

When HTTP_PROXY or HTTPS_PROXY is set, opencode attach http://127.0.0.1:<port> routes its requests (e.g. GET /config/providers) through the proxy even when NO_PROXY includes 127.0.0.1/localhost. This breaks attaching to a local server when a corporate/system proxy is configured.

The attach path connects via createOpencodeClient, which falls back to the runtime's global fetch (packages/sdk/js/src/v2/client.ts:51-56) with no proxy handling. Bun's native fetch honors HTTP(S)_PROXY but not NO_PROXY. The repo already ships a correct NO_PROXY-aware resolver (packages/opencode/src/util/proxy-env.ts, getProxyForUrl/shouldProxy), but it's only wired into the OpenAI WebSocket path (packages/opencode/src/plugin/openai/ws.ts:88) — whose own comment notes "Bun does not apply HTTP(S)_PROXY to WebSockets unless the proxy is supplied explicitly." The HTTP/attach path has no equivalent, and unlike the desktop app (packages/desktop/src/main/sidecar.ts ensureLoopbackNoProxy()) it does no loopback bypass.

Steps to reproduce

  1. export HTTPS_PROXY=http://your-proxy:8080 (and/or HTTP_PROXY)
  2. export NO_PROXY=127.0.0.1,localhost
  3. Start an opencode server, then opencode attach http://127.0.0.1:<port>
  4. The request to 127.0.0.1 still goes through the proxy instead of connecting directly.

OpenCode version

1.18.0 (Bun 1.3.14)

Operating System

Linux (WSL2)

Activity

linletian commented on Aug 16, 2026

@linletian

Additional data point on the same runtime (opencode 1.18.18 / Bun 1.3.14, plain Linux, no WSL): the loopback-proxying also bites when NO_PROXY uses CIDR notation, which is what many distros / proxy generators write by default:

HTTP_PROXY=http://10.0.0.2:8080
NO_PROXY=localhost,127.0.0.0/8,::1

Measured matrix against a local opencode serve (only NO_PROXY varied, plain fetch under Bun):

NO_PROXY fetch("http://127.0.0.1:<port>/...")
127.0.0.0/8 (CIDR) routed through proxy → 502
127.0.0.1 (literal) direct ✅
localhost direct ✅
* direct ✅

So on this Bun build, literal entries do bypass correctly — the remaining Bun-side gap is specifically CIDR matching (filed upstream as oven-sh/bun#39352). Note the practical impact is wider than attach: in-process plugins receive an SDK client whose fetch is this same Bun fetch, so plugin → http://127.0.0.1:<port> API calls (e.g. session.messages) also go through the proxy in serve mode; in TUI mode they use the in-process app.fetch and are unaffected. When such a call returns a non-2xx, at least one popular plugin (oh-my-openagent) crashes hard — code-yeongyu/oh-my-openagent#6912.

Given Bun's CIDR gap (and per #37043 the attach path ignoring NO_PROXY in some setups), an opencode-side loopback bypass for HTTP — like the desktop app's ensureLoopbackNoProxy() — would cover all of these cases in one place.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions