Skip to content

service: recovery loop spawns unbounded serve processes when service becomes unresponsive #57038

Closed as duplicate

Description

@xuhb2000

Summary
When the background service stops responding to health checks (triggered deterministically in this report by connecting nthLink, a Windows traffic-filter VPN), the client re-detects "Background service is unresponsive" every ~6s and spawns a fresh opencode serve --service each time. Each instance briefly binds port 49374, never answers HTTP, and gets replaced — ~40 processes in 3.5 minutes, repeated port 49374 ... is already in use errors, ending in Timed out waiting for the background service to start. There is no backoff or spawn cap, and the recovery storm also kills the previously healthy long-lived service. Disconnecting the VPN restores the service in ~1s.

Environment
opencode version: v2.0.28 (latest channel)
OS: Windows_NT 10.0.26200 (win32 x64)
Terminal: TERM=xterm-256color (TERM_PROGRAM unset)
Shell: Windows PowerShell 5.1
Install/channel: release / latest
Active plugins: oh-my-openagent@latest (its unrelated schema-load warnings appear in every boot, healthy or not)
Reproduction
Windows machine with nthLink 7.4.0.0 installed (kernel traffic-filter driver nfdriver + leaf proxy, fake-IP DNS in 198.18.0.0/15).
Start opencode normally; opencode api get /api/info responds in 1–2 ms, LISTENING PID on 127.0.0.1:49374 stable.
Connect nthLink.
~40s later start a new TUI (opencode), or simply wait for client health checks.
Observe for the next ~3.5 minutes (independent 2s-interval probe):
GET /api/info on 127.0.0.1:49374 times out on every request, while raw TCP connect to the same port still succeeds
LISTENING PID on port 49374 changes every ~6s (dozens of distinct PIDs)
client log repeats Background service is unresponsive; recovery cannot preserve persistent terminals every ~6s, interleaved with Managed service port 49374 on 127.0.0.1 is already in use by another process
ends with Error: Timed out waiting for the background service to start
Disconnect nthLink → service healthy again within ~1s (new stable PID, API responds in 1–2 ms).
Reproduced 3/3 within one afternoon; user reports this started after reinstalling nthLink (previous nthLink install + opencode worked fine together).

Expected Behavior
Client should back off exponentially, stop spawning duplicate service processes, and surface a clear error instead of an unbounded crash-loop storm.
A stalled service process should still answer HTTP: readiness-gate and boot-time network calls should have hard timeouts so a hung outbound path cannot block the event loop / HTTP server.
Actual Behavior
A new serve process is spawned every ~6s with no backoff or cap; port ownership churns continuously; every instance boots location services (~400ms) then goes completely silent at the HTTP level.
The environmental trigger is a third-party VPN, but the unbounded recovery loop converts a transient network stall into a multi-minute process storm, and the previously healthy service instance is lost as well.
Additional Context
Client log excerpt (opencode.log, local time 16:42–16:44, role=cli/role=server interleaved):

16:42:10 WARN Background service is unresponsive; recovery cannot preserve persistent terminals (repeats every ~6s)
16:42:11 INFO location services booted ... durationMs=490 <- new instance boots fine
16:42:48 INFO Sent HTTP response GET /api/info http.status=503
16:42:59 ERROR cli process failed: Managed service port 49374 on 127.0.0.1 is already in use ...
...
16:44:08 ERROR cli process failed: Timed out waiting for the background service to start
Independent 2s-interval probe (loopback TCP vs loopback HTTP vs outbound HTTPS) during the controlled reproduction:

17:04-17:07 (baseline, VPN off) tcp=OK info=401/1-2ms models.opencode.ai=OK200/~300ms DNS=normal
17:07:31 nthLink connects (DNS switches to fake-IP 198.18.0.1)
17:07:56 outbound slows: models.opencode.ai OK200/9457ms
17:08:12 - 17:11:48 tcp=OK info=TIMEOUT every sample (3s)
LISTENING PID changes every ~6s (~40 distinct PIDs)
meanwhile other processes (PowerShell) reach
models.opencode.ai OK200/~300ms -> network itself is fine
17:11:55 VPN disconnected -> info=401/2ms immediately, PID stable
nthLink-side log shows each opencode instance's three boot-time HTTPS calls being handed to the proxy right before the process goes silent (timestamps UTC):

09:08:28 handled process=opencode-cli.exe src=127.0.0.1 proto=tcp in=nf out=Proxy dst=models.opencode.ai:443
09:08:30 handled process=opencode-cli.exe ... dst=opencode.ai:443
09:08:30 handled process=opencode-cli.exe ... dst=registry.npmjs.org:443
-> the same process then never answers any HTTP request; ~6s later the client replaces it
Notes:

No loopback interception observed: TCP connect to 127.0.0.1:49374 kept succeeding throughout the outage; the stall is at HTTP level inside the service process (event loop appears blocked).
Workaround confirmed: disconnecting the VPN restores service within ~1s.
The third-party VPN is arguably misbehaving here too (a bug report will be filed upstream); this issue is about opencode's recovery behavior turning a network stall into a process storm.

Activity

  1. opencode-agent commented on Oct 19, 2026

    @opencode-agent
    Contributor

    Thanks for the detailed report and the probe timeline.

    I tried to reproduce this with 2.0.28 on Linux by stalling the service's outbound network in two ways. First, I routed its HTTPS traffic to a proxy that accepts connections and never replies, with loopback left direct. Second, I pointed DNS at a resolver that never answers. Your oh-my-openagent@latest plugin was configured. In both cases the service kept answering GET /api/info in 1–2 ms the whole time. The boot-time models fetch gave up on its own after 10s, the PID stayed the same, and the client never reported the service as unresponsive or started replacing it.

    So on Linux, a hung outbound connection by itself doesn't stall the service. The stall you see probably depends on Windows and nthLink's traffic-filter driver, which I can't set up here, so this needs a maintainer with a Windows machine.

    Related issues, most relevant first:

  2. neriousy commented on Oct 23, 2026

    @neriousy
    Member

    Closing as a duplicate of #54810, which tracks the same managed-service recovery/spawn loop. The Windows/nthLink network-stall reproduction has been transferred there so the retry fix can be checked against this trigger.

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

Metadata

Metadata

Assignees

No one assigned

    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