Skip to content

Bug Report: OpenCode v2 fails under proxychains (port conflict + socket closed on local service) #54523

Open

Description

@citypw

Description

proxychains opencode

Error: Managed service port 49375 on 127.0.0.1 is already in use by another process. Configure another port with opencode service set port <port> and start the service again.
    at <anonymous> (/$bunfs/root/chunk-tf6cmvsq.js:2:8693) {
  [cause]: ServeError:
      at q (/$bunfs/root/chunk-9j69fzga.js:52:46739)
      at applyHandlers (node:events:64:20)
      at emitError (node:events:44:27)
      at emitListenErrorNextTick (node:_http_server:134:12)
      at processTicksAndRejections (unknown:7:39) {
    [cause]: Error: Failed to start server. Is port 49375 in use?
        at serve (unknown)
        at <anonymous> (node:_http_server:359:39)
        at <anonymous> (node:_http_server:332:33)
        at <anonymous> (/$bunfs/root/chunk-9j69fzga.js:52:46777)
  }
}

proxychains opencode --standalone

UnknownError: An error occurred in Effect.tryPromise
    at <anonymous> (/$bunfs/root/chunk-9vasvy8p.js:24:5993)
    at ~effect/Utils/internal (/$bunfs/root/chunk-9vasvy8p.js:8:1710)
    at a (/$bunfs/root/chunk-9vasvy8p.js:24:6091)
    at processTicksAndRejections (native:7:39)
    at Tui.run (/$bunfs/root/chunk-9jsczqes.js:98:643)
    at Tui.run (definition) (/$bunfs/root/chunk-9jsczqes.js:93:17212) {
  [cause]: ClientError: Transport: The socket connection was closed unexpectedly. For more information, pass verbose: true in the second argument to fetch()
      at <anonymous> (/$bunfs/root/chunk-025j0dwc.js:2:1017)
      at async <anonymous> (/$bunfs/root/chunk-025j0dwc.js:2:1265)
      at processTicksAndRejections (native:7:39) {
    [cause]: TypeError: The socket connection was closed unexpectedly. For more information, pass verbose: true in the second argument to fetch()
        at async <anonymous> (/$bunfs/root/chunk-025j0dwc.js:2:981)
        at async <anonymous> (/$bunfs/root/chunk-025j0dwc.js:2:1265)
  }
}

Plugins

No response

OpenCode version

v2

No response

Steps to reproduce

No response

Screenshot and/or share link

No response

Operating System

Ubuntu 24.04

Terminal

No response

Activity

  1. opencode-agent commented on Oct 11, 2026

    @opencode-agent
    Contributor

    Thanks for the report. I could reproduce both errors on v2.0.26 (you didn't give a version, so I used the latest release), and they still happen on the latest dev (d21b0790).

    What's happening: proxychains also sends OpenCode's own connections to 127.0.0.1 through your SOCKS proxy. A proxy on another machine can't reach your local 127.0.0.1, so the OpenCode client can never connect to its own server:

    • proxychains opencode: the background service starts, but the client's checks to 127.0.0.1:<port> go through the proxy and fail. On the next launch, the client tries to start a second service on the same port and fails with Managed service port … is already in use by another process. The port is actually in use by OpenCode's own service.
    • proxychains opencode --standalone: the TUI can't reach its in-process server, which gives the ClientError: Transport: … error.

    The script below reproduces this with a small local SOCKS5 proxy that refuses loopback connections, the way a remote proxy would.

    Workaround: tell proxychains not to proxy loopback traffic by adding this line to your proxychains.conf (above [ProxyList]):

    localnet 127.0.0.0/255.0.0.0
    

    With that line, both opencode and opencode --standalone started normally in my test. Another option is to skip proxychains and use HTTPS_PROXY=… NO_PROXY=localhost,127.0.0.1 opencode.

    At the very least, the "already in use" error is misleading here, so I've passed this on to the maintainers.

    Related: #4284 (the same proxychains failure in v1), #52054 and #49796 (local traffic going through an HTTP proxy in v2).

    Reproduction script (repro.sh)
    #!/usr/bin/env bash
    # Reproduces #54523: opencode v2 fails under proxychains when the SOCKS proxy
    # cannot reach the client's own 127.0.0.1 (e.g. a proxy on another host).
    # Needs: proxychains4 (proxychains-ng), node, opencode (or OC_CMD="bun ... index.ts").
    set -u
    # OC_DEV=/path/to/checkout runs the CLI from source instead of `opencode` on PATH.
    if [ -n "${OC_DEV:-}" ]; then
      OC_CMD="bun --conditions=browser --preload=$OC_DEV/packages/tui/node_modules/@opentui/solid/scripts/preload.js $OC_DEV/packages/cli/src/index.ts"
    fi
    OC_CMD=${OC_CMD:-opencode}
    DIR=$(cd "$(dirname "$0")" && pwd)
    WORK=$(mktemp -d); mkdir -p "$WORK/home" "$WORK/proj"
    export HOME="$WORK/home"
    
    # Simulated remote proxy: drops CONNECTs to loopback.
    cat > "$WORK/socks5.mjs" <<'JS'
    // Minimal SOCKS5 proxy (no auth, CONNECT only) on 127.0.0.1:1080.
    // With REMOTE=1 it behaves like a proxy on another machine: the client's
    // "127.0.0.1" is not reachable through it, so loopback CONNECTs are dropped.
    import net from "node:net"
    net.createServer((c) => {
      c.once("data", () => {
        c.write(Buffer.from([5, 0]))
        c.once("data", (d) => {
          let host, i
          if (d[3] === 1) { host = [...d.subarray(4, 8)].join("."); i = 8 }
          else if (d[3] === 3) { host = d.subarray(5, 5 + d[4]).toString(); i = 5 + d[4] }
          else { host = "::1"; i = 20 }
          const port = d.readUInt16BE(i)
          console.log("CONNECT", host, port)
          if (process.env.REMOTE && /^(127\.|localhost$|::1$)/.test(host)) { c.destroy(); return }
          const u = net.connect(port, host, () => {
            c.write(Buffer.from([5, 0, 0, 1, 0, 0, 0, 0, 0, 0])); u.pipe(c); c.pipe(u)
          })
          u.on("error", () => { try { c.end(Buffer.from([5, 5, 0, 1, 0, 0, 0, 0, 0, 0])) } catch {} })
          c.on("error", () => u.destroy())
        })
      })
    }).listen(1080, "127.0.0.1", () => console.log("socks5 on 1080"))
    JS
    REMOTE=1 node "$WORK/socks5.mjs" > "$WORK/socks.log" 2>&1 &
    SOCKS=$!
    trap 'kill $SOCKS 2>/dev/null; pkill -f "serve --service" 2>/dev/null' EXIT
    sleep 1
    
    cat > "$WORK/pc.conf" <<'EOF'
    strict_chain
    proxy_dns
    tcp_read_time_out 15000
    tcp_connect_time_out 8000
    [ProxyList]
    socks5 127.0.0.1 1080
    EOF
    cd "$WORK/proj"
    # From-source runs: child server processes need the opentui preload too.
    [ -n "${OC_DEV:-}" ] && printf 'preload = ["%s/packages/tui/node_modules/@opentui/solid/scripts/preload.js"]\n' "$OC_DEV" > bunfig.toml
    run() { timeout "$1" script -qc "proxychains4 -q -f $WORK/pc.conf $OC_CMD $2" "$WORK/out.txt" >/dev/null 2>&1
      sed 's/\x1b\[[0-9;?]*[a-zA-Z]//g' "$WORK/out.txt" | tr -d '\r' | grep -E 'Error|in use|Starting' | head -6; }
    
    echo "== 1) proxychains opencode (first run starts the service, client cannot reach it)"
    run 40 ""
    echo "== 2) proxychains opencode again (service still running -> port conflict)"
    run 110 ""
    echo "== 3) proxychains opencode --standalone"
    run 60 "--standalone"
    echo "== proxy saw $(grep -c 'CONNECT 127.0.0.1' "$WORK/socks.log") loopback CONNECTs"
    echo "Workaround: add 'localnet 127.0.0.0/255.0.0.0' to proxychains.conf"

    Run it: bash repro.sh

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions