Skip to content

fix(remote): stop CI teardown reporting itself as a broken connection#182

Open
veksen wants to merge 1 commit into
mainfrom
fix-ci-teardown-broken-log
Open

fix(remote): stop CI teardown reporting itself as a broken connection#182
veksen wants to merge 1 commit into
mainfrom
fix-ci-teardown-broken-log

Conversation

@veksen

@veksen veksen commented Jul 16, 2026

Copy link
Copy Markdown
Member

Goal

Make CI run logs trustworthy: the final lines should reflect the verdict, not a scary false warning. Fixes Query-Doctor/Site#3580.

What

Before: every CI run that reached teardown logged [main] API connection broken during CI run: Error: RPC session was shut down by disposing the main stub right next to the verdict, reading as if the run was cut off mid-flight. After: an intentional teardown logs nothing; a genuine mid-run transport break still logs the broken-connection warning.

The run in the issue had completed normally — ingest succeeded, the baseline was fetched, and the exit 1 came from a correct verdict (2 untriaged regressions). The connection was never broken; the message fired during our own teardown.

How

connect() in src/remote/api-client.ts wires onRpcBroken → triggerBroken → onBroken. triggerBroken guards on a broken flag, but dispose() disposed the stub without ever setting it. Disposing the main stub makes capnweb fire onRpcBroken, so the intentional teardown reported itself as broken.

Fix: set broken = true at the top of dispose(), before disposing the stubs, so triggerBroken becomes a no-op for an intentional teardown. connectWithReconnect is unaffected — its onBroken calls dispose() after the fact, and triggerBroken already returns early when broken is set.

Read src/remote/api-client.ts first (the one-line guard + comment), then the test.

Tests

New src/remote/api-client.test.ts drives ApiClient.connect end-to-end over an in-process ws relay that answers the real auth handshake — the only setup where capnweb actually fires onRpcBroken on dispose (an in-memory MessagePort session does not reproduce it). Two cases:

  • an intentional dispose() does not call onBroken;
  • a real transport drop (server terminates the socket) still calls onBroken.

Confirmed the dispose test fails without the guard and passes with it. Full suite green (285 passed), tsc --noEmit clean, build clean.

🤖 Generated with Claude Code

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Query Doctor Analysis

3 queries analyzed

0 regressed · 0 improved · 0 new · 0 removed

2 pre-existing issues

Using assumed statistics (10000000 rows/table). For better results, sync production stats.

More detail → get_ci_run({ runId: "019f6d3a-5668-7841-8383-6d80dc1c0eb4" }) · view run · docs

At the end of a CI run, disposing the RPC stub makes capnweb fire
onRpcBroken with "RPC session was shut down by disposing the main stub".
Because dispose() never set the broken flag, that event flowed through
triggerBroken into runInCI's onBroken and logged "API connection broken
during CI run" right next to the verdict, reading as if the run was cut
off. The run had actually completed normally (Site #3580).

Set broken = true at the top of dispose() so an intentional teardown
makes triggerBroken a no-op. connectWithReconnect is unaffected: its
onBroken calls dispose() after the fact, and triggerBroken already
guards on broken.

Covered by an integration test that drives ApiClient.connect over an
in-process WebSocket relay: an intentional dispose stays silent, while a
real transport drop still reports the broken connection.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@veksen
veksen force-pushed the fix-ci-teardown-broken-log branch from 891c341 to fcc7258 Compare July 16, 2026 23:18
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