Skip to content

fix(sentry): stop reporting remote connector tools/list refresh noise - #932

Merged
kody-bot merged 4 commits into
mainfrom
cursor/sentry-triage-kody-cloudflare-24-6962
Jul 25, 2026
Merged

kody-bot merged 4 commits into
mainfrom
cursor/sentry-triage-kody-cloudflare-24-6962

Conversation

@kentcdodds

@kentcdodds kentcdodds commented Jul 25, 2026 •

Copy link
Copy Markdown
Member

Summary

Sentry KODY-CLOUDFLARE-24 reported Remote connector tools snapshot refresh failed. for the home connector. The event context was:

Timed out waiting for remote connector response to tools/list.

That path already soft-fails (clears tools, persists, continues). The timeout is the same class of remote-connector lifecycle noise as websocket disconnects (#916): flaky home networks, slow connector processes, mid-RPC disconnects.

This PR stops opening Sentry issues for expected refresh failures (timeout / disconnect / not connected / connector RPC error) and keeps an ops console.warn instead. Unexpected failures (malformed tools/list payloads, storage bugs) still rethrow into the existing message-handler Sentry capture and do not clear a still-valid tool cache. Auth rejections still capture at error level.

Test plan

  • Unit test: expected tools/list_changed refresh failure logs warn, does not call Sentry, clears tools
  • Unit test: malformed tools/list result still reports to Sentry and keeps cached tools
  • Existing remote connector session lifecycle test still passes
  • CI npm run validate green
System recap — composes existing primitives (low risk)

Mode: recap · Base: main @ 0bfcec47 · Head: cursor/sentry-triage-kody-cloudflare-24-6962

Classification: composes — observability wiring only; soft-fail behavior for expected snapshot refresh failures is unchanged.

Primitives touched

Primitive Group Impact
connector-ingress surfaces composes — expected refresh noise → console.warn; unexpected still Sentry
remote-connectors assistant composes — same session DO path; no protocol/settings change

System map

tools/list_changed (or hello) refresh fails → expected: soft-clear + warn; unexpected: rethrow to Sentry without clearing tools.

Legend: green = composes (wiring only) · amber = extended by this PR · red = new primitive · gray = context.

flowchart LR
  RC[home connector] -->|notifications/tools/list_changed| DO[RemoteConnectorSession DO]
  DO -->|tools/list RPC| RC
  DO -->|timeout / disconnect| Soft[clear tools + console.warn]
  Soft -.->|no longer| Sentry[(Sentry)]
  DO -->|malformed result / impl bug| Sentry
  DO -->|auth / invalid payload| Sentry
  classDef composes fill:#e6f4ea,stroke:#1e8e3e,color:#0d401c;
  classDef context fill:#f1f3f4,stroke:#80868b,color:#3c4043;
  class DO,Soft composes;
  class RC,Sentry context;
Loading

Risk notes

Docs

No taxonomy or architecture doc changes required.

Open in Web Open in Cursor 

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling when remote tool lists cannot be refreshed via tools/list.
    • For expected refresh failures, tools are cleared while preserving the existing connection timestamp, and a warning is emitted.
    • Malformed tools/list responses are still reported, without clearing the existing tools list.
  • Tests
    • Added WebSocket lifecycle coverage for notifications/tools/list_changed refresh failure and malformed snapshot response scenarios.

tools/list timeouts and disconnects during snapshot refresh are expected
home-connector lifecycle noise (same class as websocket closes in #916).
Keep the soft-fail clear + ops console.warn; reserve Sentry for auth and
handler bugs.

Refs KODY-CLOUDFLARE-24.
@kody-bot
kody-bot marked this pull request as ready for review July 25, 2026 06:53
@coderabbitai

coderabbitai Bot commented Jul 25, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@cursor[bot], you've reached your PR review limit, so we couldn't start this review.

Next review available in: 38 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 13f54037-9a8d-4d84-94e5-39ac3cb55769

📥 Commits

Reviewing files that changed from the base of the PR and between 6bb0d36 and fb048e6.

📒 Files selected for processing (1)
  • packages/worker/src/remote-connector/session.ts
📝 Walkthrough

Walkthrough

Remote connector tool snapshot refreshes now classify failures centrally. Expected connector failures warn, clear cached tools, and persist state; malformed or unexpected responses propagate to Sentry. Tests cover both outcomes during tools/list_changed.

Changes

Remote connector snapshot failure handling

Layer / File(s) Summary
Centralized snapshot failure classification and handling
packages/worker/src/remote-connector/session.ts
Expected timeout, connection, and disconnection failures clear and persist tools with a phase-aware warning; unexpected refresh failures are rethrown for outer Sentry handling across hello and tools/list_changed flows.
Failure outcome regression coverage
packages/worker/src/remote-connector/session.node.test.ts
Tests verify socket-loss failures suppress Sentry while clearing tools and preserving connectedAt, and malformed tools/list responses capture Sentry while retaining existing tools.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RemoteConnectorSession
  participant WebSocket
  participant SessionState
  participant Sentry
  RemoteConnectorSession->>WebSocket: Request tools/list snapshot
  WebSocket-->>RemoteConnectorSession: Return refresh result
  alt Expected connector failure
    RemoteConnectorSession->>SessionState: Clear tools and persist state
  else Malformed or unexpected response
    RemoteConnectorSession->>Sentry: Capture session error
  end
Loading

Possibly related PRs

  • kentcdodds/kody#720: Related console warning test setup in the remote connector session tests.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: suppressing Sentry noise from expected remote connector tools/list refresh failures.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/sentry-triage-kody-cloudflare-24-6962

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 25, 2026 •

Copy link
Copy Markdown
Contributor

🔎 Preview deployed: https://kody-pr-932.kody-a99.workers.dev

Worker: kody-pr-932
D1: kody-pr-932-db
KV: kody-pr-932-oauth-kv

Mocks:

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/worker/src/remote-connector/session.ts`:
- Around line 506-510: Update refreshToolsSnapshot() and its callers, including
logToolsSnapshotRefreshFailure, to distinguish expected lifecycle or log-timeout
failures from protocol/runtime failures. Preserve warning-only handling for
expected failures, but rethrow or capture malformed tools/list responses and
other implementation errors through the existing Sentry path instead of
swallowing them or clearing tools.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 06fc2ee4-a789-465a-9df6-fa9f136d242b

📥 Commits

Reviewing files that changed from the base of the PR and between 0bfcec4 and f7aa0f1.

📒 Files selected for processing (2)
  • packages/worker/src/remote-connector/session.node.test.ts
  • packages/worker/src/remote-connector/session.ts

Address review: only suppress expected lifecycle noise (timeout, disconnect,
not connected, connector RPC error). Malformed tools/list payloads and other
implementation errors still rethrow into the message-handler Sentry path and
do not clear a still-valid tool cache.

@coderabbitai coderabbitai 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/worker/src/remote-connector/session.ts (1)

586-591: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Validate all tools/list result shapes before replacing the cache.

null reaches Sentry, but result: "bad" evaluates result.tools as undefined and persists []; { tools: {} } persists an invalid cache. Validate that the result is a non-null object and that optional tools is an array, then throw so malformed payloads preserve the valid cache and use the existing Sentry path. This is a remaining instance of the previously reported malformed-payload issue.

Proposed fix
-		const result = response.result as {
-			tools?: Array<RemoteConnectorSnapshot['tools'][number]>
-		}
-		this.stateSnapshot.tools = result.tools ?? []
+		const result = response.result
+		if (result === null || typeof result !== 'object') {
+			throw new Error('Malformed tools/list result.')
+		}
+		const tools = (result as { tools?: unknown }).tools
+		if (tools !== undefined && !Array.isArray(tools)) {
+			throw new Error('Malformed tools/list tools.')
+		}
+		this.stateSnapshot.tools =
+			(tools as Array<RemoteConnectorSnapshot['tools'][number]> | undefined) ??
+			[]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/worker/src/remote-connector/session.ts` around lines 586 - 591,
Validate the tools/list payload before mutating state in the response handling
flow: ensure result is a non-null object and, when present, result.tools is an
array. Throw on malformed values so the existing Sentry path runs and the
previously persisted valid cache remains unchanged; only assign
stateSnapshot.tools and persist state after validation succeeds.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/worker/src/remote-connector/session.ts`:
- Around line 586-591: Validate the tools/list payload before mutating state in
the response handling flow: ensure result is a non-null object and, when
present, result.tools is an array. Throw on malformed values so the existing
Sentry path runs and the previously persisted valid cache remains unchanged;
only assign stateSnapshot.tools and persist state after validation succeeds.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fbdaa569-bb9a-4fbe-bc55-18d1c45cc7c0

📥 Commits

Reviewing files that changed from the base of the PR and between f7aa0f1 and e0e86c4.

📒 Files selected for processing (2)
  • packages/worker/src/remote-connector/session.node.test.ts
  • packages/worker/src/remote-connector/session.ts

Reject non-object results and non-array tools so malformed payloads keep the
prior tool cache and surface through the message-handler Sentry path.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/worker/src/remote-connector/session.ts (2)

572-576: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Restore the cache when soft-fail persistence fails.

The handler clears this.stateSnapshot.tools before persistState(). If that storage write fails, the outer Sentry path runs but the valid in-memory cache has already been lost, so subsequent reads return no tools until state is rehydrated.

Suggested fix
+const previousTools = this.stateSnapshot.tools
 this.stateSnapshot.tools = []
 console.warn(...)
-await this.persistState()
+try {
+	await this.persistState()
+} catch (error) {
+	this.stateSnapshot.tools = previousTools
+	throw error
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/worker/src/remote-connector/session.ts` around lines 572 - 576,
Update the soft-fail handler around this.stateSnapshot.tools and persistState()
so it preserves the existing tools cache, restores it if persistState() fails,
and then allows the existing outer Sentry error path to run. Keep the cache
cleared only when persistence succeeds, using the handler’s current
stateSnapshot and persistState symbols.

30-46: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Classify in-flight disconnects as expected failures.

handleDisconnect() rejects pending RPCs with Remote connector websocket closed ... before RPC response. at Line 183, but this classifier only recognizes named RPC errors plus timeout/not-connected messages. A tools/list request interrupted by a socket close will therefore still rethrow into Sentry instead of clearing and persisting tools as intended.

Use a dedicated disconnect error name/type on the rejection path rather than relying only on message matching.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/worker/src/remote-connector/session.ts` around lines 30 - 46, The
tools snapshot failure classifier must recognize in-flight disconnect
rejections. Add a dedicated disconnect error name or type in handleDisconnect()
where pending RPCs are rejected, then update
isExpectedToolsSnapshotRefreshFailure() to classify that identity as expected
while preserving the existing named-error and message checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/worker/src/remote-connector/session.ts`:
- Around line 586-589: Update the result validation in the tools/list handling
flow near the response.result check to reject arrays as well as null and
non-object values. Ensure array-valued results throw the existing “Malformed
tools/list result.” error before any tools defaulting or cache replacement
occurs.

---

Outside diff comments:
In `@packages/worker/src/remote-connector/session.ts`:
- Around line 572-576: Update the soft-fail handler around
this.stateSnapshot.tools and persistState() so it preserves the existing tools
cache, restores it if persistState() fails, and then allows the existing outer
Sentry error path to run. Keep the cache cleared only when persistence succeeds,
using the handler’s current stateSnapshot and persistState symbols.
- Around line 30-46: The tools snapshot failure classifier must recognize
in-flight disconnect rejections. Add a dedicated disconnect error name or type
in handleDisconnect() where pending RPCs are rejected, then update
isExpectedToolsSnapshotRefreshFailure() to classify that identity as expected
while preserving the existing named-error and message checks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: dedcae88-7503-42bf-9bf1-712dcf1ddd95

📥 Commits

Reviewing files that changed from the base of the PR and between e0e86c4 and 6bb0d36.

📒 Files selected for processing (2)
  • packages/worker/src/remote-connector/session.node.test.ts
  • packages/worker/src/remote-connector/session.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/worker/src/remote-connector/session.node.test.ts

Reject array-valued tools/list results, and restore the in-memory tool cache
if soft-fail persistence fails so storage bugs still reach Sentry without
blanking later reads.
@kody-bot
kody-bot merged commit c0ef268 into main Jul 25, 2026
5 of 6 checks passed
@kody-bot
kody-bot deleted the cursor/sentry-triage-kody-cloudflare-24-6962 branch July 25, 2026 07:42
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.

3 participants