Skip to content

fix: clear the connection error once polling recovers - #73

Merged
jerelvelarde merged 2 commits into
CopilotKit:mainfrom
charan-rathore:fix/clear-recovered-connection-error
Oct 5, 2026
Merged

jerelvelarde merged 2 commits into
CopilotKit:mainfrom
charan-rathore:fix/clear-recovered-connection-error

Conversation

@charan-rathore

Copy link
Copy Markdown
Contributor

Fixes #51

After the API restarted, the red connection banner stayed up because nothing cleared it on a later successful poll.

Connection notices (failed fetch, 502/504, unreadable response) are now tracked separately from action errors. A successful workspace or capture poll clears only the connection notice. Action errors still need a dismiss, and 401 handling is unchanged. The logic is in src/client/poll-notice.ts with unit tests.

Checked locally on current main (c2569bb): npx vitest run (36 files, 168 tests), tsc --noEmit, eslint and prettier all pass. The tests cover the notice logic only. I did not exercise the banner in a browser against a restarted API, and did not run npm run build.

A successful workspace or capture poll now clears only the connection
notice, so a recovered server no longer leaves the error banner up.
Errors from user actions are kept apart and still need a dismiss.

Fixes CopilotKit#51

@NathanTarbert NathanTarbert left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks @charan-rathore, splitting poll notices from action notices is the right model for #51. Pulling the logic into poll-notice.ts with its own tests makes it easy to see what clears what, and 401 handling is kept intact.

Two things worth adding, because they affect whether #51 is fully fixed.

The first is about browsers. TRANSPORT_MESSAGES only recognizes Chrome's "Failed to fetch". When the network drops, Firefox throws "NetworkError when attempting to fetch resource." and Safari throws "Load failed". In applyCaptureResult those go to the action slot, which no successful poll clears. So in those browsers the banner can still stay up after the connection recovers. One way around matching text is to treat any error that isn't an ApiError as a transport failure, since a network failure surfaces from fetch as a TypeError.

The second is that the refresh and capture polls share the connection slot. If /state keeps failing with a 503 while a thread is open and capture keeps succeeding, each successful capture clears the state poll's error. The banner then flickers or disappears while the problem is still there. A slot per poll would keep each one's error until that same poll recovers.

…ess failures as transport

Signed-off-by: Charan Rathore <180254320+charan-rathore@users.noreply.github.com>
@charan-rathore

Copy link
Copy Markdown
Contributor Author

Thanks, both points were right. Pushed a follow-up commit:

  • Any capture failure without an HTTP status (anything that is not an ApiError) now counts as a transport failure, so Firefox's "NetworkError when attempting to fetch resource." and Safari's "Load failed" clear on the next good poll. I kept 502, 504 and the unreadable-response message as transport too.
  • The state refresh and the capture poll now have their own slots, so a successful capture no longer clears a persistent /state 503, and the other way round. Dismiss clears the action notice first, then refresh, then capture.

Tests cover the three browser messages and both cross-poll cases. Ran: full vitest (171 passed) and tsc; eslint on src/client and the test file, no findings. I did not test in real Firefox or Safari, only the message handling.

Prepared with AI assistance; Charan Rathore is directing and responsible for this PR.

@jerelvelarde jerelvelarde left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Clears recovered connection failures without hiding unrelated action failures. Strong reliability fit for the template, with no added permissions or dependencies. The current revision addresses both earlier review concerns: refresh and capture notices have separate slots, and non-HTTP fetch errors are classified as transport failures without relying on browser-specific wording. 401 handling is preserved. No blocking findings.

Validation on the reviewed head: 171 tests passed; typecheck, lint, formatting, and production build passed. The five changes also passed together: 197 tests and all checks.

@jerelvelarde
jerelvelarde merged commit 1d38d42 into CopilotKit:main Oct 5, 2026
1 check passed
@charan-rathore
charan-rathore deleted the fix/clear-recovered-connection-error branch October 5, 2026 18:55
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.

Error banner stays after the server connection recovers

3 participants