Repository navigation
meta(changelog): Update changelog for 11.8.0 - #25388
Conversation
Hono forwards SDK options to each runtime SDK, but its public types only expose core options. This makes TypeScript reject supported settings such as `enableOpenTelemetrySetup`, Node transport options, and Cloudflare RPC bindings. Inherit the Node, Bun, Deno, and Cloudflare option types while retaining Hono's middleware options. Extend the existing option-preservation tests to check that these settings compile and are forwarded. Co-authored-by: Codex <codex@openai.com>
[Gitflow] Merge master into develop
ioredis 6.0.0 keeps the same `ioredis:command` / `ioredis:connect` channels and payload as 5.11, so `redisIntegration` already works with it; this adds an `ioredis-6` alias and runs the existing `ioredis-dc` expectations against both. Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…ilds (#25307) closes #25305 closes [JS-3920](https://linear.app/getsentry/issue/JS-3920) ## Description This makes the Vite plugin bundle `@sentry/tanstackstart-react` into server builds, so server spans keep parametrized names like `GET /param/$id` with the current Nitro 3. It also fixes the e2e builds that broke with TanStack Start 1.169: - The `tanstackstart-react (latest)` canary build now also installs the latest Nitro, Vite and Vite plugins. - `tanstackstart-react-cloudflare` moves to Vite 8 (as this test is using the latest minor). ## Why TanStack Start 1.169, the first stable release, needs Vite 8, so builds on Vite 7.3.2 failed. With Vite 8, the current Nitro copies the SDK into `.output/server/node_modules` instead of bundling it, so the route patterns that our plugin writes into the SDK file never reach the server. ## Test decisions The normal `tanstackstart-react` run keeps TanStack Start 1.168 with Vite 7, so only the nightly canary runs the new Nitro. We can move its pins to 1.169 at any time, to test the fix on every PR, but that drops the 1.168 coverage. ## Sentry traces Before, server span named `GET`: https://sentry-sdks.sentry.io/explore/traces/trace/0e6c6d8167f14675a7ff464b6e20cc0d/?node=span-850e1cc693d955b7&project=4510555608449024&source=traces&targetId=850e1cc693d955b7×tamp=1791873042 After, server span named `GET /param/$id`: https://sentry-sdks.sentry.io/explore/traces/trace/715f58fb9cf3470eaa235a2ad7abff73/?node=span-b4454064fab142bc&project=4510555608449024&source=traces&targetId=b4454064fab142bc×tamp=1791873013 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…25313) Reuse `ReactComponentAnnotationOptions` from `@sentry/core` so TanStack Start's annotation options share the same definition as the other React SDKs. Co-authored-by: GPT-6 <codex@openai.com>
…25312) Note: this is now backwards compatible, we can also make it pointing to the latest version only This fixes the pi-durable tests for pi-durable 1.2.0, and makes the SDK read tool results from the new `output` field. On 1.2.0, a tool call outside a tool task phase (for example, a tool that calls another tool) lost its result. ## Why pi-durable 1.2.0 (released 2026-10-12) renamed the tool result field `content` to `output`. The test tools still return `{ content }`, so since that release all pi-durable integration tests and both `(latest)` e2e variants fail on `develop`. ## Test decisions The integration suite now installs `^1.2.0` and its tools return `output`. The e2e apps keep the 1.0.0 pin and the latest variant, so their tools set both fields. The alternative is to set both fields in the integration scenarios too and keep `^1.0.0`. ## Known issues - Nested calls through the new `api.executeTool()` of pi-durable 1.2.0 are not tested yet. --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Some E2E apps need a different pnpm version than the root. The `install-pnpm` action now reads `volta.pnpm` with the same lookup the E2E runner uses for overrides. Apps keep their versions, and no workflow hard-codes pnpm anymore. The test `nuxt-5` uses pnpm 11, because pnpm 9.15.9 hangs while installing Nuxt 5 nightlies (fixed issue in #22017). pnpm 9 also rejects these apps' `pnpm-workspace.yaml` (`packages field missing or empty`). CI chose 11.10.0 only for the exact name `nuxt-5`, so `nuxt-5-sourcemaps` (#25268) got 9.15.9 and failed. The canary job ignored app pins entirely.
Prisma 8.0.0-rc.15 renamed `CollectionImpl` to `CollectionBase`, which silently dropped all Prisma operation spans, so this targets the new class and moves the tests to rc.17 (older RCs are no longer supported). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
An e2e app that uses the OpenAI integration the way a user does and sends the data to a real Sentry project, per #24747. **The app.** A plain `Sentry.init` on an express app, preloaded with `node --import`, no tunnel. The stock `openai` client talks to OpenRouter. Five routes make one real request each: a chat completion, a streamed chat completion, a forced tool call, a Responses API call, and an embeddings call. **The tests.** Each one reads the request's `gen_ai` span back through the Sentry API, like the other `*-send-to-sentry` apps, and checks op, origin, status, model, token usage, and that the prompts and answers arrived. The checks use the attribute names ingest stores, which differ from what the SDK sends (`sentry.origin` is stored as `origin`, `gen_ai.response.text` as `gen_ai.output.messages`). Ingest does not store `gen_ai.response.tool_calls` under that name, so the tool-call test checks the finish reason instead. `openai` is pinned to 7.5.0, the version the v7 integration suite uses, and a `(latest)` variant runs the same tests against `openai@latest`. Both are optional, like the other send-to-sentry apps. Closes #24747 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This is a copy of `nuxt-4-sourcemaps` for Nuxt 5 (Nitro 3), set up like `nuxt-5`: it uses the nightly builds and runs as an optional app. It differs from the Nuxt 4 test in two places: - **No intermediate client build:** Nuxt 5 writes the client build straight into `.output/public`. So the check that every client debug ID was uploaded runs only when the maps are kept. - **Existing Nuxt 5 bugs:** three assertions are skipped with TODOs, one for each bug: - The server maps have no `sourcesContent`. - Files with glob characters in the path are not uploaded. - The server maps do not reach the `.vue` files. Merge after this is merged: #25267 and #25287 (CI fix)
Pinning for now to unblock the CI. Will follow up on an actual fix for this. I'm still not sure where the fix should go.
…ig (#25326) `@langchain/core@1.2.17` changed which keys of the ambient runnable config reach runs started without a config (langchain-ai/langchainjs#11849). Our conversation id and span parenting for those runs depend on that ambient config, so this adds a test where a streamed runnable calls a tool, and the tool invokes a chain and model with no config. Nothing regressed. The spans are identical on 1.2.16 and 1.2.17, since the release only adds `context` to the keys it passes down. The scenario initializes LangChain's AsyncLocalStorage the way LangGraph does on import. Plain `@langchain/core` keeps a no-op store, so no ambient config would reach the tool without it. Closes #25293 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
follow up to #24956 This adds the Third-Party Dependency Notice from the root LICENSE to the LICENSE of each published package that has the Sentry CLI (`sentry` on npm) as a direct or transitive runtime dependency. It also replaces the BSD 3-Clause text in `packages/bundler-plugins/LICENSE` with the MIT text, which its title, `package.json` and the upstream repo already declare (I think that got it while we moved commits over to this repo) ## Why npm ships the package LICENSE in the tarball, so users of these packages never see the notice in the root LICENSE. ## Scope decisions 20 packages get the notice: `bundler-plugins`, `remix` and `react-router` depend on the CLI directly, and every package built on `@sentry/node` gets it through `@sentry/bundler-plugins`. `@sentry/hono` does not get it, because it reaches the CLI only through optional peer dependencies. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
follow up to #24998 ## Description This adds an optional Cloudflare (OpenNext) variant to `nextjs-16-tunnel`, so the tunnel route tests also run on Workers with `withSentry` from `@sentry/nextjs/cloudflare`. ## Why Only unit tests covered that `withSentry` does not sample requests to the tunnel route. The Worker sends its spans to the proxy server, so the existing check for middleware spans of tunnel requests fails when a tunnel request is sampled. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Move the four wrapper packages from `sentry-javascript-bundler-plugins` into `packages/legacy`. Each one re-exports the matching `@sentry/bundler-plugins` subpath and now releases in lockstep with the SDK.
Use `@sentry/conventions/attributes` for registered MCP keys, including
all singleton and indexed result fields. The branch now uses published
conventions `0.27.0` from `develop`, so both local result prefixes can
be removed.
Before, the SDK constructed `mcp.tool.result.0.content` from a local
prefix. After, `MCP_TOOL_RESULT_KEY_CONTENT.replace('<key>', '0')`
produces that same key. Singleton keys, values, original array indexes,
and input/output capture behavior remain unchanged. Deprecated
tool-result fields stay emitted for compatibility; this change adds no
aliases or backfill.
This is the mechanical base for network metadata (#24506), OAuth
attribution (#24508), and canonical OpenTelemetry attributes (#25060).
The latter separately adds complete serialized results in
`gen_ai.tool.call.result`.
This restores the `@sentry/core` spies that `bunserver.test.ts` creates (`startSpanManual`, `continueTrace` and `captureException`) in an `afterAll`. ## Why `bun test` runs all test files in one process, in the order in which the filesystem lists them. The spies stayed active for the next files, so when `bunHttpServer.test.ts` ran next, its request handler had no active span and two tests failed. On GitHub runners `bunRuntimeMetrics.test.ts` ran in between, and its `jest.restoreAllMocks()` hid the bug. Other runners list the files in a different order. In that file order on Linux with Bun 1.3.14, 2 of 81 tests failed before this change, and all 81 pass after it. Failed on CI: https://github.com/getsentry/sentry-javascript/actions/runs/38031083791/job/114152141693 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ts (#25277) This adds `exited()` to the integration test runner. It resolves on the `close` event of the child process. The four "should exit" tests in `thread-blocked-native` and `anr` now await it. Before, `thread-blocked-native` waited a fixed 5 s, and `anr` checked every 100 ms. `childHasExited()` had no other users and is removed. ## Why Under CI load the child process sometimes needed more than 5 s to exit, so the test failed although the process exited correctly. The describe timeout still fails a child that never exits. Failed on CI: https://github.com/getsentry/sentry-javascript/actions/runs/38031718055/job/114154033567 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…tests (#25278) This makes slow or failed Docker Compose starts in the Node integration tests visible: - Missing images are pulled in their own step. The pull and start times are logged when they take longer than 60 s. - Each failed `up --wait` attempt logs its output and the container logs before the retry. - The `mssql` healthcheck gets a 60 s start period, so a slow SQL Server start does not cause a restart. ## Why The `beforeAll` hook blocks the event loop with `spawnSync`. When it took longer than 120 s, vitest only reported "Hook timed out in 120000ms" and not what took long. This happened when the runner first had to pull the 1.5 GB `mssql` image. ## Known issues - This does not make a pull without cached images faster. The tedious suite can still reach the 120 s timeout then, but the log shows the pull time. Failed on CI: https://github.com/getsentry/sentry-javascript/actions/runs/38033058956/job/114158377266 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…k hostnames (#25282) Even if we would stay on GHA runners for now, it is still good to keep this one in as this could also happen locally. The AWS serverless E2E apps point the DSN of the Lambda at the address that the hostname of the runner resolves to. When that address is a loopback address, they now use the first external IPv4 address that is not a Docker bridge. ## Why On Namespace runners the hostname resolves to `127.0.0.1`. Inside the Lambda container, that is the container itself, so no event reached the event proxy, and each test timed out after 180 s. On GitHub runners the hostname resolves to the address of the VM, so nothing changes there. Failed on CI: https://github.com/getsentry/sentry-javascript/actions/runs/38033058956/job/114158845637 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…g the SDK (#25279) `conflictingDebugOptions.test.ts` now mocks `DEBUG_BUILD` one time, with a getter over a `vi.hoisted` value, and it imports the client, server and edge entry points one time. Before, each test called `vi.doMock` and `vi.resetModules` and imported all three entry points again, and `beforeAll` "pre-warmed" them one more time. ## Why Under CI load, evaluating the three module graphs again took longer than the 10 s hook timeout. Now the two tests take a few milliseconds (25 ms and 6 ms locally, 1.68 s before). The "vi.unmock is not at the top level" warning is also gone. Failed on CI: https://github.com/getsentry/sentry-javascript/actions/runs/38034725173/job/114166137692 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
) This moves the button of the `handlers-lcp` test page into its own block, so the image is the only LCP candidate. ## Why The space between the inline `<img>` and `<button>` was painted as a text run in `<body>` (68 px²). When it painted in the same frame as the image, Chromium gave both LCP entries the same `startTime`. web-vitals calls its callback only when the LCP value changes, so the handlers never got the image entry, and `window._LCP` stayed at 68. On Linux (Playwright v1.63.0 image, 8 workers), 3 of 60 and 3 of 120 runs failed before this change. After it, 120 of 120 passed. Failed on CI: https://github.com/getsentry/sentry-javascript/actions/runs/38217884500/job/114713949461 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Astro 7 writes the prerender build to a hidden `.prerender` folder, and our default `<outDir>/**/*` assets glob does not go into dot folders, so the upload found nothing and logged a warning. This PR adds `<outDir>/**/.prerender/**/*` to the default globs. These chunks only run at build time, so the gain is small, but it removes the warning and covers errors captured during prerendering. Also adds an `astro-7-sourcemaps` e2e app that checks the uploads for server and static output. Fixes #25304 Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
When the SDK turns on hidden source maps, it deletes them after upload with globs for `client` and `server` folders. Static output has neither folder and writes client assets to `<outDir>/_astro`, so the maps stayed in `dist` and got deployed. This also deletes maps in the `build.assets` folder, and turns the leftover-maps check back on for the static variant of the `astro-7-sourcemaps` e2e app. Found while working on #25304. --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s add orchestrion (#25043) closes #24836 closes [JS-3837](https://linear.app/getsentry/issue/JS-3837/run-the-react-router-e2e-suite-on-bun-deno-and-cloudflare-from-one-app) ## Description This fixes the Vite build when `sentryCloudflareVitePlugin` and a framework's Sentry plugin, for example `sentryReactRouter`, are in the same config. Only the first orchestrion plugin in the build now transforms modules, so apps no longer need `buildTimeInstrumentation: false`. ## Why Both plugins add the orchestrion Vite plugin. Each instrumented module was transformed twice, and the build failed because the injected `orchestrionModuleInjected` snippet was declared twice. ## Dedupe decisions Each plugin object carries an ID property, and an instance skips its work when an earlier plugin in the build has a different ID. The ID also survives SDKs that wrap the plugin with an object spread, like `@sentry/remix`. The alternative is that each framework plugin detects the Cloudflare plugin and turns its own orchestrion off. ## Known issues - When the two instances get different options, for example custom `instrumentations`, only the options of the first one apply. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
The `with_level` scenario sends six `captureMessage` calls back to back, and the test expected their events to arrive in call order. Events are prepared asynchronously before being sent, so the SDK doesn't guarantee that order, and the test occasionally failed with `info_message` arriving before `debug_message`. The test now uses `.unordered()`, so it still asserts all six messages with their levels but no longer depends on arrival order. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Before submitting a pull request, please take a look at our [Contributing](https://github.com/getsentry/sentry-javascript/blob/master/CONTRIBUTING.md) guidelines and verify: - [x] If you've added code that should be tested, please add tests. - [x] Ensure your code lints and the test suite passes (`yarn lint`) & (`yarn test`). - [ ] Link an issue if there is one related to your pull request. If no issue is linked, one will be auto-generated and linked. ### Description #15473 stopped the client plugin from reporting Nuxt errors with a 3xx/4xx status in its `app:error` hook. Nuxt also calls `vue:error` for every error that reaches the root component, fatal or not, so a page that throws `createError({ statusCode: 404 })` during setup is still reported, from the `vue:error` handler (mechanism `auto.function.nuxt.vue-error`). On client-side navigation this happens for every such 404. This applies the same check to both hooks through a shared `isIgnoredNuxtError`, and adds unit tests for the client plugin's error hooks: 3xx/4xx Nuxt errors are skipped from both hooks, 5xx Nuxt errors and non-Nuxt errors are still reported. Without the fix, the `vue:error` 4xx test fails. --------- Co-authored-by: mketiku <16418952+mketiku@users.noreply.github.com>
…#25361) TanStack Start splits route files into virtual modules such as `index.tsx?tss-serverfn-split`. The uploaded source maps kept these queries, and their paths stayed relative to the map's directory, so frames did not show the source file. The default `rewriteSources` hook now removes the split queries and makes paths relative to the project root, such as `src/routes/index.tsx`. A user's `sourcemaps.rewriteSources` still takes precedence. First PR of a stack for #21012. Refs #21012 --------- Co-authored-by: Jan Peer Stöcklmair <jan.peer@sentry.io>
…ide spans (#25285) ## What OpenAI `decisions.create` calls now create `decide <model>` spans with op `gen_ai.decide`, recorded in the same shape as Jev calls so Sentry renders them the same way: - `input` is recorded as `state`, images included as they are. - Questions and answers are keyed by question name, as the conventions define. - Choice and score question options go in `criteria`, like Jev: choices as `{ [value]: description }`, score levels as their labels. - Choice and score `probabilities` are keyed by option or score value, and score labels go in a `legend`. - `predicate` answers keep OpenAI's `{ type, probability }`, which Sentry renders as yes/no. | | OpenAI sends / returns | Recorded on the span | |---|---|---| | Evaluated input | `input: "I want a refund"` | `state: "I want a refund"` | | Questions | `[{ name: "wants_refund", type: "predicate", ... }]` | `{ wants_refund: { type: "predicate", ... } }` | | Choice question | `choices: [{ value: "billing", description: "Charges and refunds" }, { value: "other" }]` | `criteria: { billing: "Charges and refunds", other: "" }` | | Score question | `levels: [{ label: "low" }, { label: "high", description: "Blocks the customer" }]` | `criteria: ["low", "high"]`, `descriptions: { "1": "Blocks the customer" }` | | Answers | `[{ name: "wants_refund", type: "predicate", ... }]` | `{ wants_refund: { type: "predicate", ... } }` | | Predicate answer | `{ type: "predicate", probability: 0.97 }` | unchanged | | Choice answer | `choice: true`, `probabilities: [{ value: true, probability: 0.91 }, ...]` | `choice: "true"`, `probabilities: { "true": 0.91, ... }` | | Score answer | `probabilities: [{ value: 1, label: "high", probability: 0.95 }, ...]` | `probabilities: { "1": 0.95, ... }`, `legend: { "1": "high", ... }` | ### OpenAI decisions have a few things Jev does not - `predicate` questions and answers instead of `noul`, with the yes probability in `probability` - Score levels can have descriptions, recorded in `descriptions` keyed by score value - A question can come back as a refusal, `{ type: "refusal" }`, with no probability or reason - The input can hold images as base64 data URLs. ## Why OpenAI added a Decisions API that works like Jev, and these calls had no span. Related: #25253 --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
## What Adds the `node-openai-decisions-send-to-sentry` e2e app. It calls the real OpenAI Decisions API and checks the `gen_ai.decide` spans that Sentry stores, for a text and an image decision. Only this app gets the new `E2E_OPENAI_DECISIONS_API_KEY` secret. ## Why OpenRouter has no Decisions route, so this app must call OpenAI directly. --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
closes #25303 closes [JS-3918](https://linear.app/getsentry/issue/JS-3918) ## Description This applies `dataCollection.urlQueryParams` to the `Referer` header that the browser SDK collects from `document.referrer`. Sensitive query params of the previous page are now filtered in `request.headers.Referer` of error events and static transactions, and in the `http.request.header.referer` span attribute. ## Known issues We do have a button to go to this page. By now adding filters we redirect to a potential broken page, but this can't and shouldn't be fixed, as this is filtered. <img width="636" height="271" alt="Screenshot 2026-10-13 at 14 21 34" src="https://github.com/user-attachments/assets/c22d3940-3614-4590-a368-0be490ce2f56" /> ## Sentry events Before (11.7.0), the Referer has `jwt=sensitive-jwt-value`: https://sentry-sdks.sentry.io/issues/7789837458/events/b27e43ad65b7405b8e030ebbcbff37e1/?project=4510555608449024 After, the Referer has `jwt=[Filtered]`: https://sentry-sdks.sentry.io/issues/7789837458/events/e5d05ddd3fd14c40a0c24e26e962223c/?project=4510555608449024 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
`SuppressedError` is what JS throws when a cleanup (`using` / `Symbol.dispose`) fails while another error is already in flight. It keeps both errors, `error` (the new one) and `suppressed` (the original), and it has no `cause`. because of that, LinkedErrors never saw them. In Sentry I only got the generic wrapper message, "An error was suppressed during disposal". Take a look , how it looks today (node SDK): <img width="959" height="534" alt="Screenshot 2026-10-11 195752" src="https://github.com/user-attachments/assets/0bc2079a-407f-4609-b6e4-7669f47b368f" /> This change makes `aggregateExceptionsFromError` also follow `error` and `suppressed`, the same way it already follows `cause` and `errors[]`, both errors now show up as chained exceptions. If a SuppressedError has another SuppressedError inside, it goes down the chain too. And one thing I'm not sure about: I did not set `is_exception_group` on the wrapper. From [#10850](#10850) i understand that flag makes sentry ignore that entry for grouping and titles, and that was a problem for `cause` errors. But the wrapper here has a meaningless message, so maybe it should be a group. (happy to change it if you prefer.) I added tests for both errors, nested SuppressedErrors, non-Error values, and an error that only has an `error` property (it must not be treated as a SuppressedError). Fixes [#8441](#8441)
…25343) 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>
…25376) SvelteKit 3.1.0 emits a `sveltekit.endpoint` span for `+server` handlers when server tracing is on. The SDK did not know the span, so it went out with origin `manual` and no op, unlike Kit's other spans. It also broke the `sveltekit-3` e2e test, which counts the child spans of a page that fetches a `+server` route. The span now gets op `function` and origin `auto.function.sveltekit.endpoint`. The origin follows the trace origin format and the other Kit span origins (`auto.function.sveltekit.load`, `auto.function.sveltekit.action`). Its part keeps the span apart from the SDK's own `wrapServerRouteWithSentry` span (`auto.function.sveltekit`), which can now appear next to it. Under span streaming, the span also gets `sentry.description`, as Kit's other spans do, because the `function` description template needs `code.function.name`, which Kit does not set. Re: sveltejs/kit#17325 Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This PR adds the external contributor to the CHANGELOG.md file, so that they are credited for their contribution. See #25246 Co-authored-by: timfish <1150298+timfish@users.noreply.github.com>
Most e2e apps that pinned their own Node version did so to run on something newer than the old Node 20 base. Since #24343 moved the root to Node 24.21.0, those pins are either redundant or now *older* than the root (e.g. the `24.15.0` pins), so every app now simply extends the root Volta config. This also drops the Node 20 pin that #24343 added to `react-send-to-sentry` as a stopgap, since it passes on Node 24 now. Two overrides remain: - pnpm `11.10.0` in `nuxt-5` and `nuxt-5-sourcemaps`, which was bumped deliberately in #22017. - Node `20.19.5` in `tsx-express`. On Node >= 24.13 the SDK injects instrumentation through `Module.registerHooks`, whose `load` hook tsx's CJS loader bypasses (it replaces `Module._extensions` and calls `_compile` directly), so Express is never instrumented. #25351 fixes this; the pin can go once it lands. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
#25308) The `SentryCliAdapter` contract tests in `bundler-plugins` occasionally time out on the first test. Every command run through the real CLI also sends the CLI's own telemetry to `o1.ingest.us.sentry.io` and waits up to ~3s for it to flush. With that endpoint unreachable, each test takes ~3s instead of ~80ms, which leaves the first test, which also pays the CLI's cold start, too little headroom under the 5s timeout on a slow runner. Setting `SENTRY_CLI_NO_TELEMETRY` for the suite brings every test back to a few milliseconds, and the tests no longer send anything to sentry.io. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 30ec754. Configure here.
| expectModelCallAttributes(attributes, 'embeddings', EMBEDDINGS_MODEL); | ||
| expect(attributes['gen_ai.embeddings.input']).toContain('Paris'); | ||
|
|
||
| await expectOnlySpanUnderRequestSpan(traceId, 'gen_ai.embeddings', span); |
There was a problem hiding this comment.
Tests hardcode span attribute names
Low Severity
New test assertions compare span ops and attributes with string literals such as http.server, gen_ai.chat, http.request.header.referer, sentry.op, and sentry.origin. The testing conventions in the review rules require @sentry/conventions constants for those checks (as the sibling node-openai-decisions-send-to-sentry tests already do). This was flagged because it was mentioned in the review rules file.
Additional Locations (2)
Triggered by project rule: PR Review Guidelines for Cursor Bot
Reviewed by Cursor Bugbot for commit 30ec754. Configure here.
size-limit report 📦
|


No description provided.