Repository navigation
fix(cloudflare): auto-instrument when wrangler main is a package - #25343
Merged
isaacs merged 5 commits intoOct 14, 2026
Conversation
Member
Author
|
Bugbot run |
isaacs
force-pushed
the
isaacschlueter/js-3725-sentrycloudflarevite-auto-instrumentation-skips-the-worker
branch
from
October 14, 2026 02:49
90a6ab1 to
86fcec8
Compare
isaacs
added this pull request to stack #25346
October 14, 2026 03:02
isaacs
marked this pull request as ready for review
October 14, 2026 04:03
isaacs
requested review from
andreiborza and
mydea
and removed request for
a team
October 14, 2026 04:03
JPeer264
approved these changes
Oct 14, 2026
JPeer264
left a comment
Member
There was a problem hiding this comment.
Thanks for taking this. That's quite an important one
isaacs
force-pushed
the
isaacschlueter/js-3725-sentrycloudflarevite-auto-instrumentation-skips-the-worker
branch
from
October 14, 2026 16:17
b07bdc6 to
771e865
Compare
Contributor
size-limit report 📦
|
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
force-pushed
the
isaacschlueter/js-3725-sentrycloudflarevite-auto-instrumentation-skips-the-worker
branch
from
October 14, 2026 18:18
0941e83 to
1698a1d
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ 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.
isaacs
deleted the
isaacschlueter/js-3725-sentrycloudflarevite-auto-instrumentation-skips-the-worker
branch
October 14, 2026 23:36
51 tasks done
This was referenced Oct 15, 2026
nicohrubec
added a commit
that referenced
this pull request
Oct 16, 2026
#25430) Backport of: #25343 ## Differences to the original PR - `packages/cloudflare/src/vite/transform.ts`: on v10, a local class already wrapped by a named export keeps its binding (which now points at the wrapped class), so `export { Foo as default }` stays as written instead of being re-pointed at a wrapper name. - `packages/cloudflare/src/vite/autoInstrument.ts`, tests and the `cloudflare-autoinstrument-package-entry` e2e app: small adjustments to fit v10's code layout. Heads-up: this conflicts with #25407 (backport of #25345) in `packages/cloudflare/src/vite/transform.ts` and its test. Whichever lands second needs a rebase. This branch was prepared by the v10 backport automation, which was blocked at PR creation; it's opened manually now. <!-- junior-request-attribution:start --> via **Jan Peer Stöcklmair**. <!-- junior-request-attribution:end --> <!-- junior-session-footer:start --> <!-- junior-conversation-id:local%3Aweb%3A83fc948beed4fb12a54d41cb --> -- [View Junior Session in Sentry](https://sentry.sentry.io/explore/conversations/local%3Aweb%3A83fc948beed4fb12a54d41cb/?project=4510944073809921) <!-- junior-session-footer:end --> --------- Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com> Co-authored-by: Nicolas Hrubec <nicolas.hrubec@outlook.com>
renovate Bot
added a commit
to andrei-picus-tink/auto-renovate
that referenced
this pull request
Oct 17, 2026
| datasource | package | from | to | | ---------- | ------------------- | ----- | ------ | | npm | @sentry/vite-plugin | 5.4.1 | 11.8.0 | ## [v11.8.0](https://github.com/getsentry/sentry-javascript/blob/HEAD/CHANGELOG.md#1180) ##### Important Changes - **feat(bundler-plugins): Release `@sentry/webpack-plugin`, `@sentry/vite-plugin`, `@sentry/rollup-plugin` and `@sentry/esbuild-plugin` from the SDK repository ([#25095](getsentry/sentry-javascript#25095 The four standalone bundler plugins now release together with the SDK, so their version jumps from 5.4.1 to the SDK version. Each package re-exports the matching `@sentry/bundler-plugins` entry point, which we recommend for new projects. The plugin options do not change, but the update brings these breaking changes: - Node.js 20.19.0 or higher is required. - `@sentry/webpack-plugin` requires webpack 5.1 or higher. The `@sentry/webpack-plugin/webpack5` entry point still works and exports the same plugin as `@sentry/webpack-plugin`. - The plugins use the `sentry` CLI SDK instead of `@sentry/cli`. Sentry self-hosted 26.4.2 or higher is supported. Lower versions may continue to work. - Deploys that the plugins create on Vercel use the value of `VERCEL_TARGET_ENV` (`production`, `preview` or a custom name) as their environment, instead of `vercel-production` or `vercel-preview`. To keep the old value, set `release.deploy.env`. - **feat(server-utils): Instrument the OpenAI decisions API as `gen_ai.decide` spans ([#25285](getsentry/sentry-javascript#25285 OpenAI `decisions.create` calls now create `gen_ai.decide` spans. ##### Other Changes - feat(core): Support SuppressedError in LinkedErrors integration ([#25246](getsentry/sentry-javascript#25246)) - fix(astro): Delete generated source maps for static output ([#25310](getsentry/sentry-javascript#25310)) - fix(astro): Upload source maps of Astro 7's prerender build ([#25309](getsentry/sentry-javascript#25309)) - fix(browser): Apply `urlQueryParams` to the Referer header ([#25324](getsentry/sentry-javascript#25324)) - fix(cloudflare): auto-instrument when wrangler `main` is a package ([#25343](getsentry/sentry-javascript#25343)) - fix(hono): Expose runtime-specific SDK options ([#25290](getsentry/sentry-javascript#25290)) - fix(node): Instrument Prisma 8 CollectionBase from rc.15 ([#25301](getsentry/sentry-javascript#25301)) - fix(nuxt): Skip 3xx/4xx Nuxt errors in the vue:error hook ([#25341](getsentry/sentry-javascript#25341)) - fix(server-utils): Read pi-durable 1.2.0 tool results from `output` ([#25312](getsentry/sentry-javascript#25312)) - fix(server-utils): Transform modules once when two Sentry Vite plugins add orchestrion ([#25043](getsentry/sentry-javascript#25043)) - fix(sveltekit): add op and origin to Kit's `sveltekit.endpoint` span ([#25376](getsentry/sentry-javascript#25376)) - fix(tanstackstart-react): Keep parametrized route names in Nitro 3 builds ([#25307](getsentry/sentry-javascript#25307)) - fix(tanstackstart-react): Rewrite source paths of split route modules ([#25361](getsentry/sentry-javascript#25361)) <details> <summary> <strong>Internal Changes</strong> </summary> - chore: Add external contributor to CHANGELOG.md ([#25375](getsentry/sentry-javascript#25375)) - ci: Install the pnpm version that Volta pins ([#25287](getsentry/sentry-javascript#25287)) - license: Add cli FSL notice to package licenses ([#25314](getsentry/sentry-javascript#25314)) - ref(core): use shared MCP attribute conventions ([#25059](getsentry/sentry-javascript#25059)) - ref(tanstackstart-react): Reuse shared component annotation options ([#25313](getsentry/sentry-javascript#25313)) - test(browser): Keep whitespace text out of the handlers-lcp page ([#25280](getsentry/sentry-javascript#25280)) - test(bun): Restore [@sentry/core](https://github.com/sentry/core) spies after the Bun.serve tests ([#25276](getsentry/sentry-javascript#25276)) - test(bundler-plugins): Disable CLI telemetry in the CLI contract tests ([#25308](getsentry/sentry-javascript#25308)) - test(e2e): Add node-openai-decisions-send-to-sentry test app ([#25331](getsentry/sentry-javascript#25331)) - test(e2e): Add node-openai-send-to-sentry test app ([#24824](getsentry/sentry-javascript#24824)) - test(e2e): Add nuxt-5-sourcemaps test ([#25268](getsentry/sentry-javascript#25268)) - test(e2e): Inherit root Volta config in all e2e test apps ([#25369](getsentry/sentry-javascript#25369)) - test(e2e): Use an external host address for the Lambda DSN on loopback hostnames ([#25282](getsentry/sentry-javascript#25282)) - test(nextjs): Run nextjs-16-tunnel on Cloudflare ([#25161](getsentry/sentry-javascript#25161)) - test(nextjs): Switch DEBUG_BUILD with a getter instead of re-importing the SDK ([#25279](getsentry/sentry-javascript#25279)) - test(node): Await the child exit in the "should exit" integration tests ([#25277](getsentry/sentry-javascript#25277)) - test(node): Cover ioredis v6 in the diagnostics_channel suite ([#25300](getsentry/sentry-javascript#25300)) - test(node): Cover LangChain model calls made from a tool without config ([#25326](getsentry/sentry-javascript#25326)) - test(node): Log slow and failed Docker Compose starts in integration tests ([#25278](getsentry/sentry-javascript#25278)) - test(node): Unflake captureMessage with_level test ([#25358](getsentry/sentry-javascript#25358)) - test(sveltekit): Pin rollup to 4.64.5 ([#25328](getsentry/sentry-javascript#25328)) </details> Work in this release was contributed by [@kunal649](https://github.com/kunal649) and [@mketiku](https://github.com/mketiku). Thank you for your contributions!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

When wrangler
mainis 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 everymainas a path relative to the wrangler config, so no module matched the entry. The plugin now readsmainthe way@cloudflare/vite-plugindoes. 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
createIdResolverfromvite, soviteis now an optional peer dependency.this.resolve()intransformdoes 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. AresolveIdhook does not work either, becausevite:resolveresolves bare specifiers before user plugins see them.createIdResolveruses each environment's own conditions (for exampleworkerd), so it picks the same file that the Cloudflare plugin bundles.Bundled package entries often end in
export { handler as default }. The transform only wrappedexport default <expr>, so it now also wraps a default export in that form.The new
cloudflare-autoinstrument-package-entrye2e app installs a local package as the Worker entry.@sentry/astrostill needs changes beforeastro-6-cf-workerscan use a packagemain, so that app stays as it is, and will be fixed in a subsequent PR.Fixes #24522
Fixes JS-3725