Skip to content

fix(scripts): scenarios run where localhost resolves to IPv6 first - #34121

Merged
juliusmarminge merged 2 commits into
mainfrom
scenario-host-agreement
Nov 11, 2026
Merged

juliusmarminge merged 2 commits into
mainfrom
scenario-host-agreement

Conversation

@juliusmarminge

Copy link
Copy Markdown
Member

Problem

vp run scenarios and vp run scenarios:prove (added in #34007) could not run on machines that resolve localhost to ::1 first, such as the Linux worker VMs. e2e waited on http://127.0.0.1:<port> for its full 300-second startup timeout on each commit and then reported "could not run", although the app had started.

Confirmed on a fresh worker VM at 3a8c250cb0: the web dev server binds localhost, which there is [::1] only.

$ getent hosts localhost
::1             localhost ip6-localhost ip6-loopback
➜  Local:   http://localhost:35054/        # ss: [::1]:35054
127.0.0.1 -> no answer        [::1] -> 200

Setting HOST from outside cannot fix it: the dev runner deletes HOST in web modes.

Fix

The runner and the app now agree on one address by construction.

  • scripts/e2e.config.ts has one LOOPBACK constant (127.0.0.1) used for the app URL, the ready URL, and passed to the start script.
  • scripts/scenarios/start-app.ts starts the server (dev:server) and the web dev server (dev:web) separately instead of the combined dev mode, and passes the web one --host <that address> and both the same --dev-url. The allowed origin uses the same address.
  • If the web port comes up on the other loopback address anyway, the start script says so and exits, so e2e does not wait out its timeout. This branch of the code was not exercised: with --host honoured it cannot happen on current commits.

The change is in the start script, not in apps/web/vite.config.ts, because a proof runs the app of an older base commit with this checkout's scripts.

Proof, on a fresh worker VM

Branch at 53698b6cf9, after vp i:

  • vp run scenarios --target web: 2 passed in 40 s, browser download included. The app log shows Local: http://127.0.0.1:45959/.
  • vp run scenarios:prove scripts/scenarios/add-project-tab-reaches-submit.e2e.ts --base e509db3a2f^ --head e509db3a2f --upload-command "ghdrop upload": exit 0 in 106 s (it took 11.5 minutes to fail before).
{
  "failsOnBase": true,
  "passesOnHead": true,
  "baseSha": "80e62619f5c01d84579bcf70ea6d566712007412",
  "headSha": "e509db3a2f21b8e291d05ef11789c6a4ff662e9c",
  "verdict": "Proven: the scenario fails on base `80e62619f5` and passes on head `e509db3a2f`."
}
Base 80e62619f5 Head e509db3a2f
Result ❌ failed
ASSERTION_FAILED: expect.toBeFocused failed
✅ passed
after tab Base 80e62619f5: after tab Head e509db3a2f: after tab

The same two web scenarios also pass on a machine where localhost resolves to 127.0.0.1.

Also

The doc gains the command that fetches e2e's browser ahead of time, for a machine image. Verified on the VM: after it, a run downloads nothing.

node scripts/node_modules/playwright-core/cli.js install --only-shell chromium ffmpeg

Not covered

  • The iOS target was not rerun; its start path (mobile mode) is unchanged.
  • The Vite proxy still targets the server at localhost while the server binds 127.0.0.1. It worked on the IPv6-first VM (Node tries both addresses), as it does in ordinary dev there.

vp run check:changed passes.

Work by Claude Fable 5.2 in Claude Code.

🤖 Generated with Claude Code

juliusmarminge and others added 2 commits November 10, 2026 16:59
The web dev server bound `localhost`, which is ::1 alone on machines that resolve
the name to IPv6 first, while e2e waited on 127.0.0.1 until its startup timeout.
The start script now runs the server and the web dev server separately and passes
the web one the host e2e uses, and says so at once if it still binds elsewhere.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…ll command

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Nov 11, 2026
@macroscopeapp

macroscopeapp Bot commented Nov 11, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 5379f98

Macroscope's review found this PR approvable — The web scenario harness now uses an explicit IPv4 loopback address for startup and readiness, avoiding IPv6-first localhost mismatches. Effects are confined to test startup; production defaults and mobile startup remain unchanged.

You can add or adjust custom eligibility rules. Learn more.

@juliusmarminge
juliusmarminge merged commit b883156 into main Nov 11, 2026
29 of 30 checks passed
@juliusmarminge
juliusmarminge deleted the scenario-host-agreement branch November 11, 2026 01:17
fancyboi999 added a commit to fancyboi999/t3code that referenced this pull request Nov 11, 2026
…contrast

* origin/main: (480 commits)
  fix(scripts): scenarios run where localhost resolves to IPv6 first (pingdotgg#34121)
  feat(opencode): track native image job outcomes and previews (pingdotgg#34089)
  fix(web): scroll project picker to top on first result (pingdotgg#34113)
  feat(server): voice models reuse copies already on disk (pingdotgg#34096)
  fix(desktop): desktop IPC only answers the main app window (pingdotgg#34094)
  feat(claude): Fable resets are offered and redeemed apart from weekly resets (pingdotgg#34106)
  feat(scripts): scenarios prove a fix in the real app with e2e, on web and iOS (pingdotgg#34007)
  fix(web): question panel header text sits centered in its row (pingdotgg#34095)
  fix(server): a t3 thread send to a finished delegated child notifies its parent (pingdotgg#33446)
  feat(mobile): pick a voice environment once, then its method (pingdotgg#34073)
  fix(mobile): attaching larger images no longer crashes with a BigInt error (pingdotgg#34087)
  fix(server): quitting stops an agent-device daemon left by an earlier server (pingdotgg#33587)
  fix(web): sent messages keep the numbers written on list items (pingdotgg#33820)
  fix(desktop): input during window teardown no longer throws in the main process (pingdotgg#33620)
  fix(web): preserve previews during attachment preparation (pingdotgg#33949)
  feat(usage): show Muse Code limits, and xAI and Antigravity accounts from a CLIProxyAPI hub (pingdotgg#33800)
  fix(server): text generation fallback respects project provider settings (pingdotgg#33741)
  fix(web): sending from an empty citation comment clears the composer (pingdotgg#33440)
  fix(github): a proxy's 403 with Retry-After is no longer reported as a rate limit (pingdotgg#33676)
  fix(web,mobile): replace sparkles icons and ban them with a lint rule (pingdotgg#25422)
  ...

# Conflicts:
#	pnpm-lock.yaml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant