Skip to content

fix(cloudflare): Auto-instrument classes re-exported from the worker entry - #23282

Draft
JPeer264 wants to merge 2 commits into
developfrom
jp/instrument-agent-vite-plugin
Draft

fix(cloudflare): Auto-instrument classes re-exported from the worker entry#23282
JPeer264 wants to merge 2 commits into
developfrom
jp/instrument-agent-vite-plugin

Conversation

@JPeer264

Copy link
Copy Markdown
Member

Agents are different, they need special care on top of the wrangler config. Because they are marked as DurableObjects, but have a different wrapper, they need extra hacks within the Vite plugin.

Issue

Before, specific type of import/exports didn't work properly and caused manual instrumentation again: https://github.com/sergical/cuzz/blob/4ec6080865e37491ff240007bbe886f907ad1de7/src/worker/index.ts#L11-L15

Solution(s)

First one

We had to add a agent return inside resolveWrapperKind, to correctly identify Agents in there as well, so we know when to add instrumentAgentWithSentry instead of instrumentDurableObjectWithSentry

Second one

When a class gets exported right away, we need to change that export:

export { MyAgent, MyDo } from './do' 

needs to be changed to the following in order to wrap it:

import { MyAgent as __SENTRY_REEXPORT_MyAgent__, MyDo as __SENTRY_REEXPORT_MyDo__ } from './do' 
const __SENTRY_WRAPPED_MyDurableObject__ = __SENTRY__.instrumentDurableObjectWithSentry((env) => ({}), __SENTRY_REEXPORT_MyDurableObject__);
export { __SENTRY_WRAPPED_MyAgent__ as MyAgent, __SENTRY_WRAPPED_MyDo__ as MyDo } from './do' 

This should fix what was needed before: getsentry/sentry-docs#18944


Clanker description

The Vite auto-instrument transform only wrapped classes declared in the entry module. An entry that just aggregates its Durable Objects, Agents and Workflows from other files — import { MyAgent } from './agent'; export { MyAgent }, or export { MyAgent } from './agent' — got no instrumentation at all, leaving manual instrument*WithSentry wrapping as the only option.

An import binding cannot be reassigned, so instead of renaming a declaration the transform now re-points those specifiers at a fresh wrapper binding and rebuilds the export statement, carrying unrelated specifiers over verbatim.

Agent detection was blind to the same shapes: collectAgentCandidates only considered local classes, so a re-exported Agent was never even offered to the cross-module base-class walk that already knew how to resolve it.

Star re-exports (export * from './do') still cannot be wrapped — they name no binding — so the warning stays, reworded to say that rather than blaming re-exports in general.

JPeer264 and others added 2 commits August 11, 2026 11:40
…entry

The Vite auto-instrument transform only wrapped classes declared in the entry
module. An entry that just aggregates its Durable Objects, Agents and Workflows
from other files — `import { MyAgent } from './agent'; export { MyAgent }`, or
`export { MyAgent } from './agent'` — got no instrumentation at all, leaving
manual `instrument*WithSentry` wrapping as the only option.

An import binding cannot be reassigned, so instead of renaming a declaration the
transform now re-points those specifiers at a fresh wrapper binding and rebuilds
the export statement, carrying unrelated specifiers over verbatim.

Agent detection was blind to the same shapes: `collectAgentCandidates` only
considered local classes, so a re-exported Agent was never even offered to the
cross-module base-class walk that already knew how to resolve it.

Star re-exports (`export * from './do'`) still cannot be wrapped — they name no
binding — so the warning stays, reworded to say that rather than blaming
re-exports in general.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`export { X } from './x'` has no local binding: the specifier's "local" name is
an export of the *source* module. Matching it against `workerEntrypointClasses`
— which structural detection populates from this module's own AST — wrapped a
re-exported class whenever an unrelated local class happened to share its name.

Configured names are unaffected; those are keyed by exported name, which is what
wrangler binds.

Also covers the re-export path for Workflows and WorkerEntrypoints, which went
through it untested.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@JPeer264
JPeer264 requested a review from timfish August 11, 2026 12:13
@JPeer264 JPeer264 self-assigned this Aug 11, 2026
@JPeer264
JPeer264 requested a review from a team as a code owner August 11, 2026 12:13
@JPeer264
JPeer264 requested review from isaacs and mydea and removed request for a team August 11, 2026 12:13
@github-actions

Copy link
Copy Markdown
Contributor

size-limit report 📦

⚠️ Warning: Base artifact is not the latest one, because the latest workflow run is not done yet. This may lead to incorrect results. Try to re-run all tests to get up to date results.

Path Size % Change Change
@sentry/browser 30.25 kB - -
@sentry/browser - with treeshaking flags 28.43 kB - -
@sentry/browser - with treeshaking flags tracing without tracing 26.76 kB - -
@sentry/browser (incl. Tracing) 48.49 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 48.51 kB - -
@sentry/browser (incl. Tracing, Profiling) 51.39 kB - -
@sentry/browser (incl. Tracing, Replay) 87.92 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 77.29 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 92.63 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 105.31 kB - -
@sentry/browser (incl. Feedback) 47.56 kB - -
@sentry/browser (incl. sendFeedback) 35.07 kB - -
@sentry/browser (incl. FeedbackAsync) 40.22 kB - -
@sentry/browser (incl. Metrics) 31.26 kB - -
@sentry/browser (incl. Logs) 31.54 kB - -
@sentry/browser (incl. Metrics & Logs) 32.2 kB - -
@sentry/react 32.05 kB - -
@sentry/react (incl. Tracing) 50.67 kB - -
@sentry/vue 35.31 kB - -
@sentry/vue (incl. Tracing) 50.44 kB - -
@sentry/svelte 30.27 kB - -
CDN Bundle 31.51 kB - -
CDN Bundle (incl. Tracing) 48.8 kB - -
CDN Bundle (incl. Logs, Metrics) 33.72 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 50.75 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 74.26 kB - -
CDN Bundle (incl. Tracing, Replay) 86.39 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 88.29 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 92.09 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 94.09 kB - -
CDN Bundle - uncompressed 93.56 kB - -
CDN Bundle (incl. Tracing) - uncompressed 146.45 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 99.96 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 152.25 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 228.89 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 265.7 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 271.48 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 279.4 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 285.17 kB - -
@sentry/nextjs (client) 53.23 kB - -
@sentry/sveltekit (client) 48.9 kB - -
@sentry/core/server 65.43 kB - -
@sentry/core/browser 51.78 kB - -
@sentry/node 117.91 kB - -
@sentry/node/import (ESM hook with diagnostics-channel injection) 0 B added added
@sentry/node - without tracing 82.03 kB +0.01% +1 B 🔺
@sentry/aws-serverless 91.43 kB -0.01% -2 B 🔽
@sentry/cloudflare (withSentry) - minified 214.03 kB - -
@sentry/cloudflare (withSentry) 528.61 kB - -

View base workflow run

@JPeer264
JPeer264 requested review from chargome and s1gr1d and removed request for isaacs and mydea August 11, 2026 14:16
@JPeer264
JPeer264 marked this pull request as draft August 11, 2026 14:46
@JPeer264
JPeer264 removed request for s1gr1d and timfish August 11, 2026 14:46
@JPeer264

Copy link
Copy Markdown
Member Author

Put back to draft. It seems there is a double instrumentation by accident

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