Skip to content

fix(cloudflare): auto-instrument when wrangler main is a package - #25343

Open
isaacs wants to merge 5 commits into
developfrom
isaacschlueter/js-3725-sentrycloudflarevite-auto-instrumentation-skips-the-worker
Open

isaacs wants to merge 5 commits into
developfrom
isaacschlueter/js-3725-sentrycloudflarevite-auto-instrumentation-skips-the-worker

Conversation

@isaacs

@isaacs isaacs commented Oct 14, 2026

Copy link
Copy Markdown
Member

When wrangler main is a package export, such as "main": "vinext/server/fetch-handler" or "main": "@astrojs/cloudflare/entrypoints/server", the Vite plugin did not wrap the Worker. The build passed, but the bundle had no Sentry code, and the plugin gave no warning.

unstable_readConfig() resolved every main as a path relative to the wrangler config, so no module matched the entry. The plugin now reads main the way @cloudflare/vite-plugin does. A value with a JS or TS extension is a file path. Any other value is resolved with Vite, once per environment, from the wrangler config. If it does not resolve, the plugin warns that auto-instrumentation is off. For a package entry, instrument.server.* is read from beside the wrangler config.

The resolve uses createIdResolver from vite, so vite is now an optional peer dependency. this.resolve() in transform does not work: Rollup's commonjs resolver loads each module it resolves, so a resolve of the entry from the entry's own transform never finishes. A resolveId hook does not work either, because vite:resolve resolves bare specifiers before user plugins see them. createIdResolver uses each environment's own conditions (for example workerd), so it picks the same file that the Cloudflare plugin bundles.

Bundled package entries often end in export { handler as default }. The transform only wrapped export default <expr>, so it now also wraps a default export in that form.

The new cloudflare-autoinstrument-package-entry e2e app installs a local package as the Worker entry. @sentry/astro still needs changes before astro-6-cf-workers can use a package main, so that app stays as it is, and will be fixed in a subsequent PR.

Fixes #24522
Fixes JS-3725

@linear-code

linear-code Bot commented Oct 14, 2026

Copy link
Copy Markdown

JS-3725

@isaacs

isaacs commented Oct 14, 2026

Copy link
Copy Markdown
Member Author

Bugbot run

@isaacs
isaacs force-pushed the isaacschlueter/js-3725-sentrycloudflarevite-auto-instrumentation-skips-the-worker branch from 90a6ab1 to 86fcec8 Compare October 14, 2026 02:49

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

Stale Bugbot comment from a previous run.

Comment thread packages/cloudflare/src/vite/autoInstrument.ts
@isaacs
isaacs added this pull request to stack #25346 October 14, 2026 03:02
@isaacs
isaacs marked this pull request as ready for review October 14, 2026 04:03
@isaacs
isaacs requested a review from a team as a code owner October 14, 2026 04:03
@isaacs
isaacs requested review from andreiborza and mydea and removed request for a team October 14, 2026 04:03

@JPeer264 JPeer264 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for taking this. That's quite an important one

Comment thread packages/cloudflare/src/vite/transform.ts Outdated
Comment thread packages/cloudflare/src/vite/transform.ts Outdated
Comment thread packages/cloudflare/src/vite/wranglerConfig.ts
@isaacs
isaacs force-pushed the isaacschlueter/js-3725-sentrycloudflarevite-auto-instrumentation-skips-the-worker branch from b07bdc6 to 771e865 Compare October 14, 2026 16:17

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

Stale Bugbot comment from a previous run.

Comment thread packages/cloudflare/src/vite/transform.ts

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

Stale Bugbot comment from a previous run.

Comment thread packages/cloudflare/src/vite/transform.ts
@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 29.88 kB - -
@sentry/browser - with treeshaking flags 28.02 kB - -
@sentry/browser - with treeshaking flags tracing without tracing 27.92 kB - -
@sentry/browser (incl. Tracing) 52.07 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 52.08 kB - -
@sentry/browser (incl. Tracing, Profiling) 55.02 kB - -
@sentry/browser (incl. Tracing, Replay) 91.82 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 80.68 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 96.55 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 109.49 kB - -
@sentry/browser (incl. Feedback) 47.4 kB - -
@sentry/browser (incl. sendFeedback) 34.94 kB - -
@sentry/browser (incl. FeedbackAsync) 40.05 kB - -
@sentry/browser (incl. Metrics) 30.9 kB - -
@sentry/browser (incl. Logs) 31.18 kB - -
@sentry/browser (incl. Metrics & Logs) 31.81 kB - -
@sentry/react 31.7 kB - -
@sentry/react (incl. Tracing) 54.39 kB - -
@sentry/vue 38.04 kB - -
@sentry/vue (incl. Tracing) 55.01 kB - -
@sentry/svelte 29.9 kB - -
@sentry/remix (Remix 3 client bundle) 57.09 kB - -
CDN Bundle 31.64 kB - -
CDN Bundle (incl. Tracing) 52.58 kB - -
CDN Bundle (incl. Logs, Metrics) 33.84 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 54.52 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 74.77 kB - -
CDN Bundle (incl. Tracing, Replay) 90.25 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 92.18 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 96.4 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 98.34 kB - -
CDN Bundle - uncompressed 93.18 kB - -
CDN Bundle (incl. Tracing) - uncompressed 156.03 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 99.72 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 161.99 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 229.76 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 276.2 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 282.14 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 289.9 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 295.84 kB - -
@sentry/nextjs (client) 56.8 kB - -
@sentry/sveltekit (client) 52.45 kB - -
@sentry/core/server 41.12 kB - -
@sentry/core/browser 13.81 kB - -
@sentry/node 152.48 kB +0.02% +16 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 83.81 kB - -
@sentry/node - without tracing 94.61 kB +0.01% +4 B 🔺
@sentry/node - without channel injection 130.7 kB +0.01% +10 B 🔺
@sentry/aws-serverless 102.77 kB +0.01% +5 B 🔺
@sentry/cloudflare (withSentry) - minified 210.6 kB - -
@sentry/cloudflare (withSentry) 522.53 kB - -
@sentry/nextjs/cloudflare (withSentry) - minified 228.27 kB - -

View base workflow run

isaacs and others added 4 commits October 14, 2026 11:18
When wrangler `main` is a package export, such as
`"main": "vinext/server/fetch-handler"` or
`"main": "@astrojs/cloudflare/entrypoints/server"`, the Vite plugin did
not wrap the Worker. The build passed, but the bundle had no Sentry
code, and the plugin gave no warning.

`unstable_readConfig()` resolved every `main` as a path relative to the
wrangler config, so no module matched the entry. The plugin now reads
`main` the way `@cloudflare/vite-plugin` does. A value with a JS or TS
extension is a file path. Any other value is resolved with Vite, once
per environment, from the wrangler config. If it does not resolve, the
plugin warns that auto-instrumentation is off. For a package entry,
`instrument.server.*` is read from beside the wrangler config.

The resolve uses `createIdResolver` from `vite`, so `vite` is now an
optional peer dependency. `this.resolve()` in `transform` does not
work: Rollup's commonjs resolver loads each module it resolves, so a
resolve of the entry from the entry's own transform never finishes.
A `resolveId` hook does not work either, because `vite:resolve`
resolves bare specifiers before user plugins see them.
`createIdResolver` uses each environment's own conditions (for example
`workerd`), so it picks the same file that the Cloudflare plugin
bundles.

Bundled package entries often end in `export { handler as default }`.
The transform only wrapped `export default <expr>`, so it now also
wraps a default export in that form.

The new `cloudflare-autoinstrument-package-entry` e2e app installs a
local package as the Worker entry. `@sentry/astro` still needs changes
before `astro-6-cf-workers` can use a package `main`, so that app stays
as it is, and will be fixed in a subsequent PR.

Fixes #24522
Fixes JS-3725

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
For `export { handler as default }`, the transform declared
`const __SENTRY_DEFAULT_EXPORT__ = withSentry(...)` at the end of the
module. Until that line ran, the default export was in the temporal dead
zone. A circular import that read it during module evaluation threw a
`ReferenceError` and stopped the Worker from starting, where the
original `var` binding was already set.

The wrapper is now declared right after the statement that declares the
binding. It is a `var`, so an earlier read gets `undefined`, as it would
from the bundler's own `var`, and never throws.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…odule

For `export { handler as default }`, the wrapper ran right after
`handler` was declared. A handler assigned later (`let handler; ...
handler = { fetch }`) was exported as `undefined`, and a method added
later (`handler.fetch = ...`) was not instrumented, because `withSentry`
only patches the methods that exist when it runs.

The default export is now set in two steps. Right after `handler` is
declared, it is bound to `handler` as-is, so a circular import that
reads it during module evaluation still gets the handler. At the end of
the module, it is rebound to `withSentry(..., handler)`, which sees the
handler as it ends up.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@isaacs
isaacs force-pushed the isaacschlueter/js-3725-sentrycloudflarevite-auto-instrumentation-skips-the-worker branch from 0941e83 to 1698a1d Compare October 14, 2026 18:18

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 1698a1d. Configure here.

Comment thread packages/cloudflare/src/vite/transform.ts
Comment thread packages/cloudflare/src/vite/transform.ts

This branch has not been deployed

No deployments
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.

@sentry/cloudflare/vite: Auto-instrumentation skips the Worker when wrangler main is a package specifier

2 participants