Skip to content

feat(cloudflare): Bootstrap Mastra observability in bundled workers - #24381

Open
mydea wants to merge 2 commits into
feat/mastra-error-capturefrom
feat/cloudflare-mastra-e2e
Open

mydea wants to merge 2 commits into
feat/mastra-error-capturefrom
feat/cloudflare-mastra-e2e

Conversation

@mydea

@mydea mydea commented Sep 15, 2026

Copy link
Copy Markdown
Member

Adds Cloudflare coverage for Mastra — the most common non-Node way users run Mastra — as a Vite + workerd e2e app (cloudflare-mastra), and fixes the one thing that stopped it working with zero config.

On Cloudflare the Mastra integration couldn't bootstrap Mastra's observability pipeline: it resolves @mastra/observability via createRequire, which has no on-disk node_modules in workerd, so users had to construct and wire up an Observability themselves. Now @sentry/cloudflare/vite splices a static import * as ns from '@mastra/observability' into Sentry's own Mastra integration module — only when the package resolves — and records the namespace on a generic __SENTRY_ORCHESTRION__.providedModules marker; the integration reads it there before falling back to createRequire. Mastra tracing on Cloudflare now works with no observability config, matching the Node DX. The import lands in Sentry's module (not user code), stays statically analyzable (no lazy import()/createRequire in the bundle), and no-ops when Mastra isn't used.

Requires @mastra/observability to be an app dependency. The SDK never installs or bundles it — it is Mastra's tracing engine (the span factory), and without it Mastra emits only no-op spans, so there is nothing to capture. This is not new or Cloudflare-specific: it is equally required on Node, where the integration bootstraps from the @mastra/observability the app already has. On Cloudflare the Vite plugin's injection is additionally gated on it resolving at build time; if it is absent the plugin no-ops and no spans are produced (same net effect as Node).

The e2e app mirrors the node-mastra assertions (agent/model/tool gen_ai spans, tool-error capture, orchestrion dataloader nesting, an http.server span) against the Cloudflare instrumentation path, where orchestrion runs at build time. Its tool/dataloader assertions run against a live model via the existing E2E_OPENROUTER_API_KEY; the manual-route test needs no key.

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 28.96 kB - -
@sentry/browser - with treeshaking flags 27.26 kB - -
@sentry/browser - with treeshaking flags tracing without tracing 27.15 kB - -
@sentry/browser (incl. Tracing) 50.51 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 50.52 kB - -
@sentry/browser (incl. Tracing, Profiling) 53.5 kB - -
@sentry/browser (incl. Tracing, Replay) 90.07 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 79.16 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 94.77 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 107.73 kB - -
@sentry/browser (incl. Feedback) 46.46 kB - -
@sentry/browser (incl. sendFeedback) 34.01 kB - -
@sentry/browser (incl. FeedbackAsync) 39.12 kB - -
@sentry/browser (incl. Metrics) 29.98 kB - -
@sentry/browser (incl. Logs) 30.24 kB - -
@sentry/browser (incl. Metrics & Logs) 30.91 kB - -
@sentry/react 30.72 kB - -
@sentry/react (incl. Tracing) 52.81 kB - -
@sentry/vue 36.2 kB - -
@sentry/vue (incl. Tracing) 52.76 kB - -
@sentry/svelte 28.98 kB - -
CDN Bundle 30.7 kB - -
CDN Bundle (incl. Tracing) 51.01 kB - -
CDN Bundle (incl. Logs, Metrics) 32.98 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 52.99 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 73.67 kB - -
CDN Bundle (incl. Tracing, Replay) 88.56 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 90.53 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 94.64 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 96.63 kB - -
CDN Bundle - uncompressed 90.83 kB - -
CDN Bundle (incl. Tracing) - uncompressed 152.33 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 97.41 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 158.29 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 226.82 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 271.9 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 277.85 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 285.6 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 291.54 kB - -
@sentry/nextjs (client) 55.13 kB - -
@sentry/sveltekit (client) 50.93 kB - -
@sentry/core/server 37.13 kB - -
@sentry/core/browser 13.66 kB - -
@sentry/node 130.82 kB +0.14% +181 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 81.88 kB - -
@sentry/node - without tracing 89.7 kB +0.03% +26 B 🔺
@sentry/node - without channel injection 109.74 kB +0.18% +195 B 🔺
@sentry/aws-serverless 97.93 kB +0.03% +24 B 🔺
@sentry/cloudflare (withSentry) - minified 203.36 kB - -
@sentry/cloudflare (withSentry) 506.44 kB - -

View base workflow run

@mydea
mydea added this pull request to stack #24369 September 15, 2026 08:31
@mydea mydea changed the title test(cloudflare): Add cloudflare-mastra e2e test app feat(cloudflare): Bootstrap Mastra observability in bundled workers Sep 15, 2026
mydea and others added 2 commits September 15, 2026 12:24
Mirror the node-mastra e2e app on Cloudflare Workers (Vite + workerd) to
cover the most common non-Node way users run Mastra. Instrumentation is
wired at build time by @sentry/cloudflare/vite (orchestrion channels
injected into @mastra/core; mastraIntegration self-registers via the
global marker), with options sourced from instrument.server.ts.

Adapts for workerd: the Mastra instance is constructed lazily inside
fetch (so it runs after withSentry has subscribed), uses InMemoryStore
instead of @mastra/libsql, and configures @mastra/observability
explicitly with a placeholder exporter (the SDK's createRequire-based
bootstrap can't run in a bundled worker).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
On Cloudflare the Mastra integration could not bootstrap Mastra's
observability pipeline: it resolves `@mastra/observability` via
`createRequire`, which has no on-disk `node_modules` in workerd, so users
had to construct and wire up an `Observability` themselves.

`@sentry/cloudflare/vite` now splices a static
`import * as ns from '@mastra/observability'` into Sentry's own Mastra
integration module (only when the package resolves) and stashes the
namespace on a generic `__SENTRY_ORCHESTRION__.providedModules` marker.
The integration reads it there before falling back to `createRequire`, so
Mastra tracing works with zero observability config — the same DX as Node.

Simplifies the cloudflare-mastra e2e app to drop its placeholder
observability config accordingly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mydea
mydea force-pushed the feat/cloudflare-mastra-e2e branch from 17f167c to 3541554 Compare September 15, 2026 10:24
@mydea
mydea marked this pull request as ready for review September 15, 2026 11:04
@mydea
mydea requested review from a team as code owners September 15, 2026 11:04
@mydea
mydea requested review from isaacs and removed request for a team September 15, 2026 11:04
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