Skip to content

fix(sentry): drop D1 storage object-reset blips - #954

Merged
kody-bot merged 2 commits into
mainfrom
cursor/sentry-triage-kody-cloudflare-28-d3ab
Jul 26, 2026
Merged

kody-bot merged 2 commits into
mainfrom
cursor/sentry-triage-kody-cloudflare-28-d3ab

Conversation

@kentcdodds

@kentcdodds kentcdodds commented Jul 26, 2026 •

Copy link
Copy Markdown
Member

Summary

Filters Sentry noise from KODY-CLOUDFLARE-28 (Error: D1_ERROR: Internal error in D1 DB storage caused object to be reset; reference = 8t4dqqpoq1ctvjr8kca8fl4c).

One production event on MCP capability admin_user_usage failed inside readEntitlementResourceUsage → readDailyEntitlementCounter when Cloudflare D1 returned an opaque storage fault (D1DatabaseSessionAlwaysPrimary._sendOrThrow, support reference 8t4dqqpoq1ctvjr8kca8fl4c). This is transient D1 backend unavailability, not an application bug — the same class already handled for SQLITE_BUSY, long-running export blocks, Network connection lost (#952), and internal error; reference = … (#953).

PR #953 already filters the short internal error; reference = <id> form. This event used a longer Cloudflare phrasing that the exact matcher missed. This PR extends that matcher so:

  1. runD1WithRetry / cron lane skip / module-artifact transient detection treat the storage object-reset form like other D1 platform blips
  2. beforeSend (filterRetryableD1LockSentryEvent) drops matching events so these blips do not open or regress Sentry issues

The matcher still requires a reference = <token> and only accepts the two known D1 phrasings (internal error; … and internal error in D1 DB storage caused object to be reset; …), so bare "internal error" and unrelated wording stay retryable/Sentry-visible.

Siblings (client updateCurrentEntry, sandbox timeout, search validation) do not share this root cause and are left alone.

Test plan

  • d1-retry.node.test.ts matches the object-reset+reference form; rejects unreferenced object-reset and mismatched wording; retries once then succeeds
  • sentry-options.node.test.ts drops both prefixed and unprefixed object-reset forms; keeps unreferenced object-reset
  • Local npm run validate green
  • CI npm run validate green
System recap — composes existing primitives (low risk)

Mode: recap · Base: main @ 6fed00ac · Head: e4bc82d8

Classification: composes — narrow extension of the existing D1 transient matcher + Sentry beforeSend filter; no D1 schema, auth, or backup export contract changes.

Primitives touched

Primitive Group Impact
(unmatched) d1-retry.ts / sentry-options.ts observability composes — treat D1 storage object-reset + reference = … like SQLITE_BUSY for retry + Sentry drop

System map

Transient D1 storage object-reset faults still fail uncovered queries; Sentry and retry paths no longer treat that blip as a novel platform failure.

Legend: green = composes (wiring only) · amber = extended by this PR · red = new primitive · gray = context (unchanged, included only when an edge crosses it).

flowchart LR
	d1Retry["d1-retry<br/>Transient D1 matcher"]:::touched
	sentryOpts["sentry-options<br/>beforeSend filters"]:::touched
	d1AppDb["d1-app-db<br/>D1 app database"]:::untouched
	d1AppDb -->|"object to be reset; reference"| d1Retry
	d1Retry -->|"isRetryableD1LockSentryEvent"| sentryOpts
	classDef touched fill:#1a7f37,color:#fff
	classDef extended fill:#9a6700,color:#fff
	classDef added fill:#cf222e,color:#fff
	classDef untouched fill:#57606a,color:#fff
Loading
Open in Web Open in Cursor 

Summary by CodeRabbit

  • Bug Fixes
    • Expanded automatic retries for transient Cloudflare D1 “internal error … object to be reset” failures so operations recover after the retry delay.
    • Updated Sentry event filtering to suppress expected D1 “internal error … reference = …” noise (including prefixed/unprefixed variants), while keeping truly non-retryable cases unmodified.
  • Tests
    • Added coverage for additional D1 error message variants and verified retry behavior using fake timers.
  • Documentation
    • Clarified which D1 internal errors are treated as temporary, retryable, and suppressible for Sentry.

Extend the retryable D1 internal-error matcher to Cloudflare's
"Internal error in D1 DB storage caused object to be reset; reference = …"
so runD1WithRetry and beforeSend treat it like other opaque D1 faults.

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@coderabbitai

coderabbitai Bot commented Jul 26, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The D1 retry matcher now recognizes referenced storage object-reset errors as retryable. Tests cover classification, retry execution, and Sentry filtering for prefixed and unprefixed variants.

Changes

D1 retry classification

Layer / File(s) Summary
Expand D1 internal-error matching
packages/worker/src/d1-retry.ts, packages/worker/src/sentry-options.ts
Referenced D1 storage object-reset messages are included in retryable internal errors, with updated retry and Sentry suppression documentation.
Validate retry and filtering behavior
packages/worker/src/d1-retry.node.test.ts, packages/worker/src/sentry-options.node.test.ts
Tests verify classification, delayed retry success, and Sentry removal for prefixed and unprefixed object-reset messages.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main change: treating D1 storage object-reset errors as transient and dropping them from Sentry.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/sentry-triage-kody-cloudflare-28-d3ab

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.

@cursor
cursor Bot marked this pull request as ready for review July 26, 2026 07:32
@github-actions

github-actions Bot commented Jul 26, 2026 •

Copy link
Copy Markdown
Contributor

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

Worker: kody-pr-954
D1: kody-pr-954-db
KV: kody-pr-954-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/d1-retry.node.test.ts`:
- Around line 51-64: Add a negative test in
packages/worker/src/d1-retry.node.test.ts around isRetryableD1LockError to
verify the unreferenced object-reset message returns false, while preserving the
existing referenced cases. Also update
packages/worker/src/sentry-options.node.test.ts around filterSentryEvent to
verify the corresponding unreferenced event is returned unchanged; both tests
should cover the required-reference boundary without changing matcher behavior.
🪄 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: 943850ca-8ae0-4c1c-a5ff-9dfa39cec523

📥 Commits

Reviewing files that changed from the base of the PR and between 6fed00a and 4dfcfb3.

📒 Files selected for processing (4)
  • packages/worker/src/d1-retry.node.test.ts
  • packages/worker/src/d1-retry.ts
  • packages/worker/src/sentry-options.node.test.ts
  • packages/worker/src/sentry-options.ts

Cover the required-reference boundary so a bare storage object-reset
message is neither retried nor dropped by beforeSend.

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.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.

3 participants