fix: bound startup network waits for offline hosts by PJ-Zetier · Pull Request #57745 · anomalyco/opencode · GitHub
Skip to content

fix: bound startup network waits for offline hosts - #57745

Draft
PJ-Zetier wants to merge 2 commits into
anomalyco:devfrom
PJ-Zetier:startup-network-bounds
Draft

PJ-Zetier wants to merge 2 commits into
anomalyco:devfrom
PJ-Zetier:startup-network-bounds

Conversation

@PJ-Zetier

Copy link
Copy Markdown

Issue for this PR

Closes #57742
Related: #2224, #19197

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

On hosts where connections hang instead of failing fast (airgapped/firewalled networks), startup stalls for minutes because several awaited operations have no bound. Two commits:

  1. fix: bound startup-path network waits for offline hosts — Arborist installs get a timeout (2 min install / 15 s freshness check, via a test-overridable Npm.Timeouts reference) surfaced as InstallFailedError, with the staging-dir cleanup proven to still run on interrupt; the TUI's pre-renderer file.list call gets a 10 s abort with a process.cwd() fallback instead of a frozen blank terminal; URL skill sources get a 10 s client bound; the initial remote-instruction fetch is forked like the later refreshes; OAuth refresh and the Console config fetch get 10 s / 5 s bounds flowing into their existing failure paths.
  2. fix: do not gate TUI/server readiness on plugin installs — the TUI ready gate opens after 10 s while reconcile keeps running in the background (plugins activate late instead of blocking first use), and the server's plugin activation latch bounds each plugin setup (15 s, interruptible acquire so promise-based plugins can't wedge it) and each install (30 s), routing into the existing failed-plugin handling.

Bounds are generous, failures land on the same non-fatal paths as before, so slow-but-working networks are unaffected.

How did you verify your code works?

New deterministic tests that hang a local server/registry and assert the bound fires: packages/core/test/npm.test.ts (also asserts no .staging-* dir is left behind), skill-discovery.test.ts, plugin-failure.test.ts (activation latch releases, next plugin still activates), plugin/module.test.ts. Typecheck clean in util, core, tui (and dependents server, cli). Touched-package suites were compared against base 92242b55 — only pre-existing failures, byte-identical lists. A network-namespace airgap harness (dropped SYNs + hanging DNS) measured the unbounded npm retry ladder these bounds cap: ~100-160 s per cold plugin spec with hanging DNS, ~6-13 min with black-holed TCP.

Screenshots / recordings

N/A — the TUI shows the same loading states, just bounded.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

🤖 Generated with Claude Code

PJ-Zetier and others added 2 commits October 21, 2026 11:19
On airgapped or degraded networks (hanging DNS, black-holed TCP) TUI
startup stalled on unbounded waits: plugin installs ran npm's full retry
ladder with no opencode-side deadline while the first frame and plugin
activation awaited them, and the pre-paint location lookup, URL skill
index fetch, remote instruction fetch, OAuth refresh, and Console config
load all had no timeout. Bound Arborist reify and the registry check in
Npm (2m install / 15s check through an overridable Context.Reference),
abort the TUI pre-paint requests after 10s and fall back to the client
directory, bound the skill catalog client, Console config pipeline, and
credential refresh, and fork the initial remote-instruction fetch off
plugin activation the way later refreshes already run. Staging-directory
cleanup on interrupt is preserved, and hung-registry and hung-catalog
behavior is covered by deterministic loopback tests.

Refs anomalyco#2224
Refs anomalyco#19197
Refs anomalyco#51022

Co-Authored-By: Claude Mythos 5 <noreply@anthropic.com>
On airgapped or degraded networks a cold plugin install can hang in
npm's retry ladder for minutes, and both the TUI first frame and the
server plugin-activation latch waited on it without a bound. Stop
gating TUI readiness on the first reconcile after 10 seconds while it
keeps running in the background, so plugins still activate when it
finishes. Bound each plugin setup at 15 seconds through the existing
failed-slot path so activation always settles, and bound the
per-package install await at 30 seconds so an unreachable registry
fails that plugin and the rest of the generation proceeds. Config
changes and the periodic re-check retry failed installs as before, and
hung setups and installs are covered by deterministic tests.

Refs anomalyco#2224
Refs anomalyco#19197

Co-Authored-By: Claude Mythos 5 <noreply@anthropic.com>
@PJ-Zetier
PJ-Zetier force-pushed the startup-network-bounds branch from c871fe7 to 76450ed Compare October 21, 2026 15:21

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Startup hangs for minutes on offline/airgapped hosts: plugin installs and startup fetches are unbounded

1 participant