Skip to content

fix(installer): retry the network check before cancelling the install - #287

Merged
mvalancy merged 2 commits into
devfrom
fix/installer-network-retry
Nov 11, 2026
Merged

mvalancy merged 2 commits into
devfrom
fix/installer-network-retry

Conversation

@mvalancy

Copy link
Copy Markdown
Member

Fixes the red in the Comprehensive suite's "Installer & Deploy Config" job on #281 (job 130418062294). The "stranded" installer case ended with:

⚠ Network connectivity test failed
ℹ This may cause download failures. Continue? [y/N] ✗ Installation cancelled - network required

Cause: the pre-flight check made one 5-second request to github.com. With no terminal attached, the Continue? prompt reads "no", so one dropped request cancelled the whole install. Anyone running the one-line installer on a shaky connection would see the same thing.

Fix: the new network_reachable asks up to 3 times, 2 seconds apart, before calling the network unreachable. GRAPHDONE_NETWORK_TRIES and GRAPHDONE_NETWORK_PAUSE override the count and the pause. Nothing else in the check changes:

  • wget is still used when there is no curl;
  • with neither tool, the check passes;
  • the prompt is the same.

Test: installer-contract.mjs now runs the real network_reachable and check_network against a fake curl:

  • two failures and then a success: the install continues, with no warning;
  • three failures: it cancels;
  • TRIES=1: it asks once.

The new test fails on the previous install.sh. node --test tests/toolchain/installer-contract.mjs passes 6/6.

🤖 Generated with Claude Code

The pre-flight check made one 5 s request to github.com. With no terminal,
one dropped request answered its Continue? prompt with no and cancelled
the whole install; CI's installer test hit this on 2026-11-11 (job
130418062294, the stranded case). network_reachable now asks up to three
times, 2 s apart (GRAPHDONE_NETWORK_TRIES / GRAPHDONE_NETWORK_PAUSE).

installer-contract runs the real functions against a fake curl: two
failures then success continues, three failures cancel, and TRIES=1 asks
once. It fails on the previous install.sh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

🧪 Comprehensive Test Suite

  • Unit suites (Node 22.18.0 & 24.x) — core, web, server, mcp-server: ✅ passed
  • Installer & deploy config: ✅ passed

Full-stack smoke gate runs in the CI workflow.

@mvalancy

Copy link
Copy Markdown
Member Author

Independent review (72c44db)

node --test tests/toolchain/installer-contract.mjs passes 6/6. I also ran both functions under dash, the /bin/sh that the shebang and curl … | sh use, with set -e. It tried 3 times then cancelled, and GRAPHDONE_NETWORK_TRIES=0 asked once. set -e is safe here: the function only runs under if !, and the && return lists are exempt anyway. install.sh does not use set -u.

The test harness is sound. The fake curl comes first on PATH, so a real /usr/bin/curl is never reached. On a noexec tmpdir the test fails loudly (no calls file) instead of passing by mistake.

Findings

  1. should-fix: the wget call (install.sh:453) retries inside every attempt. GNU wget defaults to --tries=20 and retries connect timeouts with a 1–10 s backoff. wget 1.21 made 20 connects to a black-holed address. That is about 4 min per attempt (20×5 s + 145 s). Failure scenario: a machine with only wget, behind a firewall that drops traffic to github.com, now shows a frozen "Checking network ● ● ● ●" for about 12 min before cancelling (about 4 min before this PR). Fix: add --tries=1, now that the loop does the retrying.
  2. should-fix (older than this PR; a follow-up is fine): the [y/N] prompt (install.sh:468) can never be answered. check_network & runs as an async job, and a shell without job control gives such a job /dev/null as stdin. In dash, echo y | sh -c 'f(){ read -r r || r=n; echo $r; }; f & wait' prints n. So after 3 failures every install cancels, with or without a terminal, and wait $network_pid then exits under set -e. The test comment's "on a run with no terminal" understates this.
  3. nit: install.sh:457. If GRAPHDONE_NETWORK_TRIES is not an integer (abc, 2.5), [ -ge ] errors, so return 1 never runs and the loop never ends. Under dash with pause 0 it made about 1,200 curl calls in 3 s. A fix: case $tries in ''|*[!0-9]*) tries=3;; esac.
  4. nit: the curl worst case is 3×5 s + 2×2 s = 19 s, but the dots stop after 3 s (6 × 0.5 s), so the line sits still for about 16 s. The animation loop could run for as long as the job does.
  5. nit: the test runs the functions under bash (installer-contract.mjs:175). Users run them under sh, so running the test under sh would catch dash-only breakage. They do pass under dash today. The wget branch has no test.

🤖 Generated with Claude Code

…e retry input

Review of #287:
- The Continue? prompt ran inside the background check_network job, whose
  stdin is empty, so it could never be answered. Only network_reachable runs
  in the background now; the prompt runs after it, in the foreground.
- Prompts read the terminal (ask_continue), not stdin: under curl | sh stdin
  is the script itself. With no terminal the answer is no. The disk-space
  and macOS prompts use it too.
- wget gets --tries=1 (its default of 20 tries could hold the install for
  minutes on a silently dropped route).
- A non-number GRAPHDONE_NETWORK_TRIES/PAUSE falls back to the default
  instead of looping forever.
- The dots keep moving while retries run, and a continued install says
  GitHub was not reachable instead of Connected.

The contract now runs the functions under sh with only fakes on PATH: curl
and wget paths, bad input, and the terminal-vs-stdin answer. 3 of its 8
tests fail on the previous commit and on dev.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mvalancy

Copy link
Copy Markdown
Member Author

Thanks. All five findings are addressed in d4235e8:

  1. wget retries: wget now gets --tries=1. A test checks the flag and that the wget-only path retries.
  2. Unanswerable prompt: only network_reachable runs in the background now. The prompt runs after wait, in the foreground.
    • It reads the terminal (ask_continue, which reads /dev/tty), not stdin, because under curl … | sh stdin is the script itself. With no terminal the answer is no.
    • The disk-space and macOS prompts use the same helper, since they had the same stdin problem.
    • Tests cover three cases: a terminal "y" continues, a terminal "n" cancels, and a "y" on stdin with no terminal cancels.
  3. Bad retry values: a non-number GRAPHDONE_NETWORK_TRIES or GRAPHDONE_NETWORK_PAUSE falls back to the default, with a test.
  4. Animation: the dots keep moving until the check ends. A continued install now says GitHub wasn't reachable instead of "Connected".
  5. Shell: the contract runs the functions under /bin/sh, with only fakes on PATH.

installer-contract.mjs passes 8/8. 3 of those 8 fail on the previous commit and on dev.

🤖 Generated with Claude Code

@github-actions

Copy link
Copy Markdown

🧪 Comprehensive Test Suite

  • Unit suites (Node 22.18.0 & 24.x) — core, web, server, mcp-server: ✅ passed
  • Installer & deploy config: ✅ passed

Full-stack smoke gate runs in the CI workflow.

@mvalancy

Copy link
Copy Markdown
Member Author

Merge verification for d4235e8:

  • CI passed:
    • CI run 43027322476.
    • Comprehensive Test Suite run 43027322669, whose "Installer & Deploy Config" job runs the real installer in a container, fresh, update and stranded.
    • Prod Stack Smoke is skipped on PRs.
  • Merge ref: the parents of refs/pull/287/merge are af3f55d (dev's tip) and d4235e8 (the head). Its tree 6b596d8 is identical to git merge-tree --write-tree origin/dev d4235e8.
  • Review: both rounds' findings are fixed (see the reply above). installer-contract.mjs passes 8/8, and 3 of those tests fail on dev.

Merging to dev.

@mvalancy
mvalancy merged commit 25a6a5e into dev Nov 11, 2026
24 checks passed
@mvalancy
mvalancy deleted the fix/installer-network-retry branch November 11, 2026 13:44
mvalancy added a commit that referenced this pull request Nov 11, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mvalancy added a commit that referenced this pull request Nov 11, 2026
No conflicts: dev changed only the installer and its contract test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant