Skip to content

Upgrade Sentry JavaScript SDKs to v11 #2334

Closed

Description

@mydea

Summary

Upgrade @sentry/node and @sentry/nitro from 10.65.0 to v11 (11.9.0 or later). v11 replaces import-in-the-middle with channel-based instrumentation (orchestrion) and changes several init options. Use build-time instrumentation in the Nitro build instead of a runtime --import hook.

Migration guide: https://docs.sentry.io/platforms/javascript/guides/node/migration/v10-to-v11/

Problems to solve

1. Build-time instrumentation

  • @sentry/nitro's withSentryConfig adds only source maps and the Nitro request channel. It does not instrument libraries.
  • juniorNitro() must add the orchestrion Rollup plugin. Options:
    • sentryOrchestrionPlugin from @sentry/server-utils/orchestrion/rollup. This needs @sentry/server-utils as a direct dependency, pinned to the same version as @sentry/node.
    • sentryRollupPlugin from @sentry/node/rollup. This also adds the source map plugin, which duplicates the @sentry/nitro upload.
  • Remove the bundleOpenTelemetryLoaderHooks workaround. v11 does not use import-in-the-middle.
  • nitro dev does not bundle node_modules, so dev gets no library instrumentation. The current --import ./instrument.mjs does not give it under v11 either.
  • Remove instrument.mjs, cross-env, and NODE_OPTIONS=--import from the example app and the junior init scaffold. server.ts already calls initSentry() first.

2. Data collection (sendDefaultPii → dataCollection)

  • v11 removes sendDefaultPii. When dataCollection is not set, v11 collects more data than v10.
  • Collect only incoming request bodies (httpBodies: ["incomingRequest"]). Outgoing calls carry model prompts and provider responses that the payload filter does not see.
  • Set databaseQueryData: false so that query spans never carry parameter values.
  • Decide if cookie, header, and user-info defaults are correct.

3. Removed and changed options

  • Remove traceLifecycle, registerEsmLoaderHooks, streamGenAiSpans, and enableLogs.
  • Keep SENTRY_ENABLE_LOGS=false behavior: drop logs in beforeSendLog.
  • withStreamedSpan is a no-op. beforeSendTransaction has no effect in stream mode. Remove the transaction scrubber.
  • beforeSendSpan receives StreamedSpanJSON, which uses name, attributes, and status ok or error. Update the tests that read description or data.
  • StartSpanOptions.kind is removed.

4. Database spans

  • v11 auto-instruments pg, pg-pool, and Neon. If db/tracing.ts stays, each query gets duplicate spans.
  • Proposal: remove db/tracing.ts and use the automatic spans.
  • The query text is the same in both, and neither records parameter values.
  • The automatic spans lose these attributes:
  • The automatic spans add pg-pool.connect and pg.connect spans, db.user, and db.connection_string.

5. Model call (gen_ai) spans

  • Junior calls models through pi-ai. pi-ai calls client.beta.messages.create(...).asResponse() and parses the SSE stream itself.
  • Because of this, the automatic Anthropic span has no token usage, output, or finish reason. It never records cost.
  • The Sentry SDK has no pi-ai integration. The pi-ai usage helpers are used only by the pi-durable and flue integrations.
  • Keep the manual gen_ai spans. They are the only source of tokens and cost.
  • Disable the automatic AI provider integrations (Anthropic, OpenAI, Google, Mistral). Each model call now produces two gen_ai.chat spans.
  • Track the upstream pi-ai integration: feat(server-utils): Add pi-ai integration sentry-javascript#25869. When it is released, remove the filter and decide if the manual gen_ai spans can go.

6. Other manual instrumentation to remove

  • Remove the http.server.request webhook span. The automatic http.server span replaces it.
  • Remove the GET files.slack.com span. The automatic fetch span replaces it.
  • Keep the Slack Web API retry spans. Slack sends errors in 200 responses, so only these spans carry app.slack.api_error_code.
  • Keep the sandbox egress span. It controls trace continuation.
  • withSpan: Sentry sets the error status when a callback throws, but it does not set error.type.
    • Keep the error.type catch.
    • Do not overwrite an error.type that the callback already set. The current code replaces values such as rate_limited with the error name.
    • Remove setSpanStatus("error") calls that come immediately before a throw.

7. Telemetry contract and dashboards

  • Update TELEMETRY.md and the docs observability page (database and webhook sections).
  • v11 renames span ops and attributes (for example http.method and gen_ai.system) and uses low-cardinality span names. Update the saved queries, alerts, dashboards, and sampling rules.
  • captureMessage now attaches stack traces by default. This can create new issue groups.

8. Lockfile

  • pnpm install leaves @sentry/node@10.65.0 in the injected workspace package snapshots. Prune the orphaned entries.
  • Use the pinned pnpm (11.8.0).

Verification

  • Build the example app and run check-vercel-output.mjs.
  • Run the build with SENTRY_DEBUG=1. Confirm Bundler plugin ran, injected libraries=[...]. The list must include hono, pg, @neondatabase/serverless, and @anthropic-ai/sdk.
  • Deploy a Vercel preview. Confirm that spans, logs, and errors reach the project.

Activity

  1. self-assigned this
    on Oct 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions