anomalyco / anomalyco/opencode

VS Code Beta extension (opencode-v2) hardcodes `--port=4096` — panel fails to open whenever port 4096 is in use

Open
#49,006 0 comments 0 reactions 1 assignee View on GitHub

@Hona is already working on this.

Since Sep 14, 2026.

2.0
Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Summary

The OpenCode Beta VS Code extension (sst-dev.opencode-v2, v0.1.1) spawns its
backend with a hardcoded port:

opencode serve --hostname=127.0.0.1 --port=4096

(ServerManager.startServer calls createOpencodeServer({ port: 4096, ... }), and
the SDK default client is baseUrl: "http://localhost:4096".)

Because the port is explicit, Server.listen takes the no-fallback path
(startWithPortFallback: if (opts.port !== 0) return startListener(opts, opts.port)),
so if 4096 is already bound, the server exits with code 1 and the panel fails with:

Failed to open OpenCode panel: Server exited with code 1
Server output: Warning: OPENCODE_SERVER_PASSWORD is not set; server is unsecured.
Error: Unexpected error
ServeError

(The useless last line is a separate, already-reported bug: #38738, #46263.)

Steps to reproduce

  1. Occupy port 4096 with anything:
    • nc -l 4096, or
    • an opencode acp session (e.g. Zed's opencode agent integration), or
    • opencode web / opencode serve, or
    • the OpenCode panel in another VS Code window
  2. In VS Code, click the OpenCode activity-bar icon (or run "Open OpenCode Assistant").
  3. Panel fails with the error above.

Expected behavior

The extension should let the opencode process select the port itself instead of
pinning 4096. The CLI already implements the ideal behavior for a default port:
startWithPortFallback tries 4096 and falls back to any free port
(startListener(opts, 4096) |> Effect.catch(() => startListener(opts, 0)))
— this is why multiple opencode acp sessions coexist fine. Passing --port=0
would give the extension that behavior for free, the port is bound atomically by
the server process (no scan-then-bind race on the extension side), and
createOpencodeServer already parses the actual server URL back from stdout, so
the extension machinery for a dynamic port is already in place.

Alternatively, attach to an already-running compatible server (see #7629) instead of
spawning a new one.

Impact

  • Only one VS Code window can ever use the panel at a time (each window's
    extension host spawns its own server on the same fixed port).
  • The panel cannot coexist with Zed's opencode ACP agent, the desktop app, or a
    manual opencode serve/web — whoever starts first wins, everyone else gets an
    opaque ServeError.
  • Closing the panel tab doesn't even free the port; the server outlives the webview
    (onDidDispose only clears the panel reference), so a window reload is required.

Environment

  • Extension: sst-dev.opencode-v2 v0.1.1
  • opencode CLI: 1.18.30 (homebrew, macOS arm64)
  • VS Code: 1.137.0

Related

  • #38738 — bind failures print bare "Unexpected error / ServeError"
  • #46263 — generic error when port is already in use
  • #39390 — ACP failing on second session (fixed by the port fallback; the extension
    should get the same treatment)
  • #7629 — connect to existing server instead of starting a new one

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.