Description
opencode --server <url> fails when the server URL has a path prefix (e.g. behind a reverse proxy that routes /ws/<id>/ to an OpenCode server).
$ OPENCODE_PASSWORD=... opencode --server http://localhost:8888/ws/ca607df5
Error: Server at http://localhost:8888/ws/ca607df5 did not provide a compatible V2 health response
[cause]: ClientError: UnexpectedStatus
[cause]: Error: {"status":404}
The server is reachable: curl http://localhost:8888/ws/ca607df5/api/info returns {"version":"2.0.12",...}.
The generated promise client (packages/client/src/promise/generated/client.ts) builds request URLs with new URL(descriptor.path, options.baseUrl). Because every descriptor.path starts with /, the URL spec replaces the base path, so the request goes to http://localhost:8888/api/info instead of http://localhost:8888/ws/ca607df5/api/info. The Effect client uses HttpClientRequest.prependUrl and joins correctly, so only the promise client (CLI, TUI, web) is affected.
Plugins
None
OpenCode version
2.0.12
Steps to reproduce
- Run
opencode serve --port 4096 and put it behind any proxy that forwards /ws/x/* to it (or Bun.serve that strips the /ws/x prefix).
- Run
opencode --server http://localhost:<proxy-port>/ws/x.
- Observe the 404 health error above, while
curl <proxy>/ws/x/api/info succeeds.
Also reproducible without a proxy:
import { OpenCode } from "@opencode/client/promise"
const client = OpenCode.make({ baseUrl: "http://localhost:8888/ws/abc", fetch: async (input) => { console.log(String(input)); return Response.json({}) } })
await client.server.info() // logs http://localhost:8888/api/info
Screenshot and/or share link
No response
Operating System
macOS 26
Terminal
Ghostty
Description
opencode --server <url>fails when the server URL has a path prefix (e.g. behind a reverse proxy that routes/ws/<id>/to an OpenCode server).The server is reachable:
curl http://localhost:8888/ws/ca607df5/api/inforeturns{"version":"2.0.12",...}.The generated promise client (
packages/client/src/promise/generated/client.ts) builds request URLs withnew URL(descriptor.path, options.baseUrl). Because everydescriptor.pathstarts with/, the URL spec replaces the base path, so the request goes tohttp://localhost:8888/api/infoinstead ofhttp://localhost:8888/ws/ca607df5/api/info. The Effect client usesHttpClientRequest.prependUrland joins correctly, so only the promise client (CLI, TUI, web) is affected.Plugins
None
OpenCode version
2.0.12
Steps to reproduce
opencode serve --port 4096and put it behind any proxy that forwards/ws/x/*to it (orBun.servethat strips the/ws/xprefix).opencode --server http://localhost:<proxy-port>/ws/x.curl <proxy>/ws/x/api/infosucceeds.Also reproducible without a proxy:
Screenshot and/or share link
No response
Operating System
macOS 26
Terminal
Ghostty