feat(cloudflare): Auto-register Flue instrumentation in bundled workers - #24476
Open
RulaKhaled wants to merge 3 commits into
Open
RulaKhaled wants to merge 3 commits into
RulaKhaled wants to merge 3 commits into
Conversation
Flue is registered, not patched — `instrument()` writes into module-scope state — so instrumenting it needs a reference to that module's own binding, and no channel payload carries one. On Node the user supplies it by calling `instrument()` themselves, which stays the only route there. In a bundled worker there is no `node_modules` to resolve one from, so it is supplied at build time instead. Two halves, mirroring how Mastra reaches a worker: - `flueIntegration()` registers the instrumentation when the `@flue/runtime` namespace is on the orchestrion marker, and no-ops when it is not. A `registrationOnly` orchestrion entry is what installs it on a bundler-only SDK: evaluating `@flue/runtime` registers the factory on the marker. That also keeps the integration reachable under `sideEffects: false`, which would otherwise let the bundler drop the module and the registration with it. - `@sentry/cloudflare/vite` splices a static `@flue/runtime` import into Sentry's own Flue integration module and exposes the namespace on `providedModules`. Two things the Mastra provider does not have to handle. `@flue/runtime` is ESM-only, so `createRequire().resolve()` throws `ERR_PACKAGE_PATH_NOT_EXPORTED` on it and the existence check goes through the ESM resolver. And the namespace is exposed through a getter rather than assigned: the snippet is prepended to Sentry's module, which the bundler may evaluate before `@flue/runtime` is initialized, so assigning it stores `undefined` — the key lands on `providedModules` with nothing behind it. An app that also calls `instrument()` itself is unaffected: its own registration wins and the integration swallows the resulting `InstrumentationAlreadyInstalledError`. Node is unchanged. `moduleInjectedTransforms` is wired into the bundler paths only, and Sentry stays external in a Flue node build, so neither half applies there and `flueIntegration()` installs as a no-op. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Contributor
size-limit report 📦
|
RulaKhaled
added this pull request to stack #24478
September 17, 2026 14:18
…ation The build-time presence check used `import.meta.resolve(spec, parentURL)`. The `parentURL` argument is ignored without `--experimental-import-meta-resolve`, so the check resolved from Sentry's own install rather than the app's, and it compiles to `undefined(...)` in this package's CJS build, where it threw and fell through to a `createRequire` fallback that always fails for an ESM-only package. Injection was therefore skipped outright on the CJS path and wherever Sentry is not installed beneath the app. It now resolves with `createRequire` from the Vite root and counts `ERR_PACKAGE_PATH_NOT_EXPORTED` as a hit: `@flue/runtime` publishes no `require` condition on any subpath, so that error means the package is present, while a missing one reports `MODULE_NOT_FOUND`. Also narrows the registration catch to `InstrumentationAlreadyInstalledError` so a changed `instrument()` contract surfaces instead of becoming a debug log, bounds the supported range at `<3.0.0`, drops the unused `flueModuleNames` export, and removes `flueIntegration()` from the default integrations — it has no binding to read on Node, where registering stays a manual `instrument(Sentry.createFlueInstrumentation())` call. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Collaborator
Author
|
bugbot run |
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.
Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 97b7ed7. Configure here.
…try.init()` Core calls `integration.setup()` unguarded, and Cloudflare runs `Sentry.init()` inside the request wrapper, so rethrowing an unexpected `instrument()` failure would take down the handler — and every later request, since the client is never cached. A duplicate registration stays a debug log; anything else now warns that Flue spans will not be recorded, which keeps the failure visible without making it fatal. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
RulaKhaled
marked this pull request as ready for review
September 18, 2026 09:14
RulaKhaled
requested review from
isaacs and
mydea
and removed request for
a team
September 18, 2026 09:14
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.

Flue is registered, not patched —
instrument()writes into module-scope state — so instrumenting it needs a reference to that module's own binding, and no channel payload carries one. A bundled worker has nonode_modulesto resolve one from, so this supplies it at build time.@sentry/cloudflare/vitesplices a static@flue/runtimeimport into Sentry's own Flue integration module and exposes the namespace onprovidedModules;flueIntegration()reads it there and registers. AregistrationOnlyorchestrion entry installs the integration on a bundler-only SDK and keeps it reachable undersideEffects: false.@flue/runtimeis ESM-only, so the presence check resolves withcreateRequirefrom the Vite root and countsERR_PACKAGE_PATH_NOT_EXPORTEDas a hit — the package publishes norequirecondition on any subpath, while a genuinely missing one reportsMODULE_NOT_FOUND. The namespace is exposed through a getter rather than assigned, because the bundler may evaluate Sentry's module before@flue/runtimeis initialized.An app that also calls
instrument()itself is unaffected: its own registration wins, and only the resultingInstrumentationAlreadyInstalledErroris swallowed. On Node registering stays a manualinstrument(Sentry.createFlueInstrumentation())call —flueIntegration()is not among the default integrations there.Verified end to end in #24477.