Skip to content

opencode2 became stuck starting its managed background server #41696

Closed

Description

@SirStisx

Description

opencode2 became stuck starting its managed background server. It repeatedly spawned serve --service, but never reported the underlying error.

Plugins

No response

OpenCode version

OpenCode: 0.0.0-next-17090

Steps to reproduce

The managed service was configured to use port 49374, which was already occupied by Ollama.

Running the server directly exposed the otherwise hidden error:

Managed service port 49374 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.

opencode2 service start should surface the port-conflict error immediately rather than silently spawning repeated serve --service attempts.

Screenshot and/or share link

No response

Operating System

macOS, arm64

Terminal

ghoosty tmux

Activity

  1. github-actions commented on Aug 11, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    If your issue is distinct (e.g. specific to the managed service / opencode2 service start flow rather than opencode serve directly), feel free to clarify and we can keep it open as a separate tracking item.

  2. opencode-agent commented on Aug 12, 2026

    @opencode-agent
    Contributor

    Addressed by #41793. Managed service contenders now retain a bounded stderr tail and append it to nonzero-exit/signal startup failures, so port conflicts surface the existing actionable remediation instead of only Server process exited with code 1. Effect, Promise, and real CLI boundary regressions cover the behavior. Closing as resolved on the v2 branch.

  3. nulluserid commented on Aug 17, 2026

    @nulluserid

    Reproduced a remaining form of this on 0.0.0-beta-17498, after #41793.

    Port 49374 was occupied by an unregistered older opencode2 serve --service process. Plain opencode2 repeatedly spawned contenders and eventually returned:

    Timed out waiting for the background service to start
    

    Running opencode2 serve --service directly correctly exposed the actionable port-conflict error.

    The likely remaining gap is contender overlap: recognizeIncumbent can take 15 seconds, while Service.ensure keeps up to two contenders. A finished contender’s captured failure is returned only when no other contender remains. When another contender is still running, that failure is removed and discarded. This can repeat until the overall timeout, hiding the stderr added by #41793.

    Stopping the old listener immediately restored normal managed startup.

    Environment: Fedora Linux 44 x86_64, OpenCode 0.0.0-beta-17498.

  4. suse-coder commented on Aug 26, 2026

    @suse-coder

    This is what i get :

    timestamp=2026-08-26T14:25:53.050Z level=INFO run=e15c8c4d message="cli starting" version=0.0.0-beta-18155 channel=beta local=false args="[\"serve\",\"--service\"]" role=cli
    timestamp=2026-08-26T14:25:57.834Z level=ERROR run=2f998337 message="cli process failed" cause="Cause([Fail(Error: Managed service port 49374 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. (cause: ServeError (cause: Error: Failed to start server. Is port 49374 in use?)))])" args="[\"serve\",\"--service\"]" role=cli
    timestamp=2026-08-26T14:25:58.158Z level=INFO run=3973746d message="cli starting" version=0.0.0-beta-18155 channel=beta local=false args="[\"serve\",\"--service\"]" role=cli
    timestamp=2026-08-26T14:26:08.486Z level=ERROR run=e15c8c4d message="cli process failed" cause="Cause([Fail(Error: Managed service port 49374 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. (cause: ServeError (cause: Error: Failed to start server. Is port 49374 in use?)))])" args="[\"serve\",\"--service\"]" role=cli
    timestamp=2026-08-26T14:26:09.152Z level=INFO run=d041c690 message="cli starting" version=0.0.0-beta-18155 channel=beta local=false args="[\"serve\",\"--service\"]" role=cli
    timestamp=2026-08-26T14:26:13.622Z level=ERROR run=3973746d message="cli process failed" cause="Cause([Fail(Error: Managed service port 49374 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. (cause: ServeError (cause: Error: Failed to start server. Is port 49374 in use?)))])" args="[\"serve\",\"--service\"]" role=cli
    timestamp=2026-08-26T14:26:13.988Z level=INFO run=3a268f39 message="cli starting" version=0.0.0-beta-18155 channel=beta local=false args="[\"serve\",\"--service\"]" role=cli
    timestamp=2026-08-26T14:26:16.071Z level=ERROR run=34997653 message="cli process failed" cause="Cause([Fail(Error: Timed out waiting for the background service to start)])" args="[\"-c\"]" role=cli
    timestamp=2026-08-26T14:26:24.660Z level=ERROR run=d041c690 message="cli process failed" cause="Cause([Fail(Error: Managed service port 49374 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. (cause: ServeError (cause: Error: Failed to start server. Is port 49374 in use?)))])" args="[\"serve\",\"--service\"]" role=cli
    timestamp=2026-08-26T14:26:29.471Z level=ERROR run=3a268f39 message="cli process failed" cause="Cause([Fail(Error: Managed service port 49374 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. (cause: ServeError (cause: Error: Failed to start server. Is port 49374 in use?)))])" args="[\"serve\",\"--service\"]" role=cli
    
    

    opencdoe2 then does not start. but nothing is using that port: lsof -nP -iTCP:49374 -sTCP:LISTEN shows nothing

    Image
  5. benknab commented on Sep 8, 2026

    @benknab

    Still reproducible on opencode2 v0.0.0-beta-19242 on macOS arm64.

    Running opencode2 repeatedly tried to start the background server, then returned:

    Starting background server...
    Error: Timed out waiting for the background service to start
    

    The log at ~/.local/share/opencode/log/opencode.log and running opencode2 serve --service --print- logs --log-level debug exposed the underlying error:

    Managed service port 49374 on 127.0.0.1 is already in use by another process.
    

    lsof -nP -iTCP:49374 showed nothing, but netstat -anv -p tcp | rg 49374 showed macOS’s
    symptomsd listening on *.49374. A separate socket bind test confirmed “Address already in use.”

    Switching to a free port restored startup:

    opencode2 service set port 49375
    opencode2 service start

    Confirmed the service was listening on 127.0.0.1:49375. The remaining problem is that the CLI still
    hides the actionable port-conflict error behind a generic timeout.

  6. sghng commented on Sep 14, 2026

    @sghng

    Reproduced on the release channel, opencode v2.0.3 (macOS 26 / Darwin 27, arm64, bun global install) — so this has shipped to stable, not just next/beta.

    Root cause confirmed in code (v2 branch):

    • packages/cli/src/server-process.ts:149 — the spawned serve --service correctly detects EADDRINUSE and produces the actionable message, including the service set port hint.
    • packages/client/src/effect/service.ts:122 — a finished contender's failure is returned only when contenders.size === 0. Because the ensure loop keeps one candidate plus one lock probe in flight, each failure arrives while another contender is still pending, so the specific error is dropped every iteration; line 138 then throws the generic Timed out waiting for the background service to start with no cause. Same pattern in packages/client/src/promise/service.ts:59.
    • Suggested fix: retain the most recent contender failure and attach it as cause to the final timeout error.

    One extra data point on how the port gets poisoned with no visible listener: in my case lsof -nP -iTCP:49374 -sTCP:LISTEN showed nothing, and a manual Python bind() with SO_REUSEADDR still failed with EADDRINUSE. The culprit was a stale ESTABLISHED loopback connection, 127.0.0.1:49383 -> 127.0.0.1:49374, held by the Tailscale GUI app (no tailscale serve/funnel config — a coincidental ephemeral-range collision; the hidden peer end was likely a root-owned process, invisible to user-level lsof). On Darwin, SO_REUSEADDR only permits rebinding when prior sockets are in TIME_WAIT; an active socket with that local port blocks bind() regardless. Quitting Tailscale closed the connection and the managed service started immediately and healthily.

    So "nothing is listening on the port" does not rule out this failure mode — lsof -nP -iTCP:<port> without the LISTEN filter (or netstat -an) is needed, which makes the missing error message even more costly.

    (Full environment and log excerpts in #49009, closed as a duplicate of this issue.)

  7. jensenojs commented on Sep 22, 2026

    @jensenojs
    Contributor

    latest/dev/beta/next hard-code the managed port to 49374, which is inside the OS ephemeral range (macOS default 49152–65535). The kernel can hand that port to an unrelated process or outbound connection at any time, so the collisions reported here (symptomsd above, the Tailscale loopback connection in #49009) are not user misconfiguration — they follow from the port choice.

    Separately: the supervisor marks a spawned child unhealthy after requestTimeout: 2000 and respawns every spawnDelay: 5000 with no attempt cap. Any start slower than the probe window turns a single bind failure into a permanent spawn storm; we can reproduce the storm with the port completely free.

    Two asks:

    1. Pick the managed port outside the ephemeral range (or negotiate a free one).
    2. Use a readiness handshake instead of a fixed 2s window, and cap/back off respawns.
  8. bilbonotry commented on Sep 24, 2026

    @bilbonotry

    On linux with opencode CLI 2.0.6, each time I start opencode I get ERROR (#1): Error: Timed out waiting for the background service to start.
    IMHO it should not start 2 background service processes :
    Image

  9. neriousy commented on Oct 20, 2026

    @neriousy
    Member

    Fixed by #41793 and #50784: the background service now keeps the first startup failure, such as the port-in-use error, and reports it instead of respawning until a generic timeout. This shipped in v2.0.23. If you still get 'Timed out waiting for the background service to start' without the underlying error on that version or later, comment and we'll reopen.

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions