Repository navigation
meta(changelog): Update changelog for 11.12.0 - #26248
Conversation
**Why:** Fixes the open follow-redirects advisories (3 high). Lockfile only, since the parents use `^` ranges. The remaining 1.16.0 copy comes from `axios@1.18.1` in nx 22 and goes away with #26110. Dependabot alert: https://github.com/getsentry/sentry-javascript/security/dependabot/3402 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…26116) **Why:** Fixes the open `@modelcontextprotocol/server` advisories (3 high, 1 medium) by bumping our node-integration-tests devDependencies to 2.4.0. The MCP suites pass locally. Dependabot alert: https://github.com/getsentry/sentry-javascript/security/dependabot/3385 **Unsure about:** `@flue/runtime@2.3.0` (latest) pins `@modelcontextprotocol/client` to exactly 2.0.0, so the 2 client alerts stay open until flue updates. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
**Why:** Fixes the open vite 6.x and 7.x advisories. Both copies are transitive and come in through `^` ranges, so this only changes the lockfile. `vite@5.4.21` stays: it only comes from the `astro@4` devDependency baseline, and there is no patched 5.x. Dependabot alert: https://github.com/getsentry/sentry-javascript/security/dependabot/3340 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
[Gitflow] Merge master into develop
… fails midway (#26023) When a streamed OpenAI, Anthropic or Google GenAI response threw partway through, for example on a dropped connection, the `gen_ai` span still ended `ok`. The stream wrappers had `try/finally` with no `catch`. They now set `internal_error`, as Workers AI does. Google sets `cancelled` when the caller's `abortSignal` fired, while its timeouts stay errors. `messages.stream()` failures now keep partial usage too. A consumer that stops with `break` keeps the span `ok`. One that throws into the generator, which `Readable.from` does when a piped client disconnects, records `internal_error`. Fixes #25994 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
… or model-less bodies (#26124) ## What Bedrock `InvokeModel` and `InvokeModelWithResponseStream` calls now always get a span. - A request body passed as bytes is read. - A request body that is not JSON, or a request without a `modelId`, no longer drops the span. ## Why Parsing the request body threw before the span started, so these calls had no span at all. Extracted from #26118. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
… default export (#26132) **Why:** The debug ID proxy statically re-exports the entry's default export so downstream bundlers can tree-shake, which makes esbuild warn with `import-is-undefined` whenever an entry has no default export. esbuild can't suppress a diagnostic per file, so the plugin sets `logOverride['import-is-undefined'] = 'silent'` in `initialOptions`, same as it already forces `metafile`. The proxy's path, suffix and namespace stay as they are, so other plugins, source maps and the metafile are unaffected. Tradeoff: this silences the warning for the whole build. A user-provided `logOverride` for that id wins, so it can be turned back on. Supersedes #26123, which relied on an undocumented esbuild heuristic and changed the proxy's namespace and path in ways other plugins observe. **How to review:** Four lines in `packages/bundler-plugins/src/esbuild/index.ts`, plus `test/esbuild/entry-without-default-export.test.ts`. Closes #25885 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…26136) **Why:** On SvelteKit 3 the fetch wrapper reads `navigating` from `$app/state` before every request. When a `$effect` calls `fetch` synchronously, that read made `navigating` a dependency of the effect, so it re-ran (and re-sent its requests) on every navigation. The read now goes through `untrack`. `svelte` is marked external in rollup so the import resolves to the app's Svelte 5, and a small build-time `.d.ts` declares `untrack` because the package is type-checked against Svelte 4. **How to review:** The fix is one line in `navigationState.svelte.ts`. The new e2e test in `sveltekit-3` fails without it (4 requests instead of 1). Closes #26129 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ailure (#26131) ## What Bedrock streaming spans now show failures and always end. - A `ConverseStream` or `InvokeModelWithResponseStream` stream that fails sets the span status to error, or to cancelled when the caller aborted it. - A streaming response without a stream, or without a `modelId`, no longer leaves the span open. ## Why Failed streams showed as successful, and some streaming spans were never sent. Extracted from #26118. --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
**Why:** nx 22 pins `axios@1.18.1`, which has open advisories, and every 22.x release does. nx 24 drops axios. We skip nx 23 because it pins `undici@7.29.0`, which is still vulnerable, while 24.0.3 pins the patched 7.30.1. 24.0.4 is too new for our `minimumReleaseAge`. Dependabot alert: https://github.com/getsentry/sentry-javascript/security/dependabot/3311 **How to review:** The only config change is `affected.legacy: true`, added by the official nx 24 migration so `nx affected` (`test:pr`) keeps selecting whole projects instead of individual tasks. The other nx 23/24 migrations made no changes. **Unsure about:** nx 23 dropped Node 20 support, but our `Node (20.19) Unit Tests` job still runs nx on Node 20 (through `test:pr:node`). It passes today and nx declares no `engines`, so nothing blocks it, but a future nx release could break that job. If that happens, the job would need to run nx on the repo's Node version and only the tests on Node 20. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…#25749) `CompiledGraph.stream()` produced no `gen_ai.invoke_agent` span, so the chat and tool spans of a streamed run had no agent span above them. LangGraph runs the graph as soon as `stream()` is called, whether or not anyone reads it, so the span now follows the run. It ends on the run's own `handleChainEnd`/`handleChainError`, and the output comes from the final state, the same way `invoke()` records it. `invoke()` keeps its single span. The shared setup also no longer writes Sentry's metadata and callbacks into the caller's config, and a graph seen by both `instrumentStateGraph()` and the integration is wrapped once, with the manual options winning. **Known limitation.** When a caller stops reading early, LangGraph keeps running the graph but never reports the run's end. After a `break` the span ends at the break, so later nodes' spans start after it. After `reader.cancel()` or a client disconnecting from `new Response(stream)`, the span never ends. Replaces #23615. Co-authored with @psh4607 from that PR. Fixes #19626 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Seongho.Bak <psh30095@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…etected (#25857) **Why:** Under `bun run` there is no `Module.registerHooks`, so the runtime injection never registers and the channel integrations stay silent, including their error capture. The only hint was a `debug.warn`, so on Bun this is now an always-on `consoleSandbox` warning that points to `@sentry/bun/plugin`. Node keeps the debug-only message. Closes #23882 --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: isaacs <i@izs.me>
This PR adds the external contributor to the CHANGELOG.md file, so that they are credited for their contribution. See #25857 Co-authored-by: isaacs <9287+isaacs@users.noreply.github.com>
…ESM (#26086) **Why:** In native ESM, `fsIntegration` crashed with `Cannot assign to read only property`, because it patched the read-only `import * as fs` namespace. It now patches the mutable `fs` object behind the default export. A plain `import fs from 'fs'` isn't an option: our rollup `interop: 'esModule'` setting would turn it into `require('fs').default` in the CJS build, which is undefined. After patching, it calls `syncBuiltinESMExports()` so named imports (`import { readFile } from 'fs'`) pick up the patched functions. That call is wrapped in try/catch because Cloudflare workerd exports it but throws when it's called. **How to review:** The fix is in `instrumentation.ts`. The fs suite now runs in both ESM and CJS. On Bun and Deno, the ESM `node:fs` exports aren't tied to the object we patch, so only `fs.promises` calls get spans there. For that reason those ESM tests run on Node only. The named-import test is ESM-only, because CJS destructuring copies the functions before the patch is applied. **Unsure about:** `syncBuiltinESMExports()` updates the ESM exports of every builtin module, not only `fs`. It only makes patches applied to the CJS objects visible to ESM importers, so it shouldn't affect anything else. Closes #25950 --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…er under one invoke_agent span (#25995)
…o can load @sentry/node (#26155) Importing `@sentry/node` under Deno before 2.8.2 would fail due to #26086 named-imported `syncBuiltinESMExports`, which those versions only expose on the default export of `node:module`, fixed by reading it off the module namespace instead. I found this while running an exports check on different runtimes, it is very low impact and severity as I don't expect deno users to run the Node SDK stuff there, but this didn't break before either. Feel free to close if too edgy.
Migrate to https://conventions.sentry.dev/ Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
**Why:** TypeSafe integration tests assume all four decide spans arrive in one streamed container. Collecting across envelopes removes that batching assumption while preserving every span assertion, including waiting for late children after the `main` segment. Not sure if this actually fixes it but worth a shot I have seen this flake couple of times. Co-authored-by: OpenAI Codex <codex@openai.com>
**Why:** Fixes Dependabot alerts [3366](https://github.com/getsentry/sentry-javascript/security/dependabot/3366), [3365](https://github.com/getsentry/sentry-javascript/security/dependabot/3365) and [3250](https://github.com/getsentry/sentry-javascript/security/dependabot/3250) (body-parser DoS, high). Bumps body-parser 1.20.4 → 1.20.9 and 2.3.0 → 2.4.0. All parents (express 4/5, @apollo/server) already allow these versions, so it is a lockfile refresh plus the direct `^2.4.0` in node-integration-tests. Dev/test-only. It also pulls in newer qs and content-type through body-parser. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…rototype chains (#26162) **Why:** The patched `toString` looked up `__sentry_original__` through the prototype chain. If that chain loops through a Proxy, the lookup overflows the stack, while native `toString` works fine. We now only read it when it's an own property, which is where `markFunctionWrapped` puts it. The Hono proxies only exposed it through a `get` trap, so they now report it as an own property too. Closes #25963 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…26147) ## What Bedrock input tokens now include tokens read from and written to the prompt cache, for Converse, ConverseStream, and Claude InvokeModel (streamed or not). - Cache read and cache write token counts are now recorded. - Converse, ConverseStream, and Claude InvokeModel spans now record total tokens, like the other AI integrations. ## Why Bedrock and Anthropic report only uncached prompt tokens as input, so cached calls showed far fewer input tokens than were used. Extracted from #26118. --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…e errors (#25967) **Why:** `normalize()` is documented to always return a value, using the `**non-serializable**` marker when something goes wrong — but it could throw itself. Both places that build that marker interpolated the caught value into a template literal, and that conversion throws for a symbol (`Cannot convert a Symbol value to a string`) and for an object with no usable `toString`. A property getter throwing either one is enough to make `normalize()` throw during event preparation. The caught value is now converted with `String()` inside a try/catch, falling back to fixed text, so callers only ever get the marker. **How to review:** One small helper in `packages/core/src/utils/normalize.ts`, used by the two catch blocks there. The new tests in `normalize.test.ts` cover a getter throwing a symbol, a getter throwing a null-prototype object, and the `stringifyValue` catch failing with a symbol. I verified the fix by running the issue's reproduction against the source directly (both cases threw before, both return the marker after, ordinary inputs unchanged). I could not complete a full local `pnpm install` in my environment, so CI will be the first full suite run — flagging that honestly rather than claiming a green local run. **Unsure about:** Opening this as a draft without a prior maintainer go-ahead on the issue — happy to adjust the approach if you'd rather handle it differently. Closes #25920 Co-authored-by: Andrei <168741329+andreiborza@users.noreply.github.com>
**Why:** The `Client` constructor always called `setupWeightBasedFlushing` for logs and metrics, so every bundle carried the log and metric flush, envelope and size-estimation code, even apps that never capture either. Flushing is now set up in `_INTERNAL_captureSerializedLog` / `_INTERNAL_captureSerializedMetric` when a client's buffer is first created. That is the single entry point every log or metric passes through before it can be flushed: `_INTERNAL_captureLog`/`captureMetric`, and direct callers of the serialized variants. Setup still runs before the first `afterCaptureLog`/`afterCaptureMetric` emit. Logs and metrics behave as before: the same 800 KB weight threshold, the idle timer, `_flushInterval`, and draining on `flush()`/`close()`. The only difference is that a client with nothing buffered no longer registers these hooks. Flushing an empty buffer was already a no-op. Savings with esbuild 0.27.7 (minify, ESM, browser, `__SENTRY_DEBUG__: false`) on a tracing-only setup (`BrowserClient` + `browserTracingIntegration`): **2,068 B raw / 445 B br-11** (131,185 → 129,117 B raw). Locally, size-limit gzip for `@sentry/browser` goes from 30,403 to 29,885 B, and for `@sentry/browser (incl. Tracing)` from 52,727 to 52,173 B. **How to review:** The helper and estimators moved unchanged into `utils/weightBasedFlushing.ts`. The "close flushes the logs buffer" test now captures a log first. It used to spy on `_INTERNAL_flushLogsBuffer` with an empty buffer, which no longer reflects the contract. Closes #26145 <!-- junior-request-attribution:start --> via @BYK. <!-- junior-request-attribution:end --> <!-- junior-session-footer:start --> <!-- junior-conversation-id:agent%3Aced2e9146c6143efef718a62effeb4d1 --> -- [View Session in Sentry](https://sentry.sentry.io/explore/conversations/agent%3Aced2e9146c6143efef718a62effeb4d1/?project=4510944073809921) <!-- junior-session-footer:end --> --------- Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com> Co-authored-by: BYK <126780+BYK@users.noreply.github.com>
This PR adds the external contributor to the CHANGELOG.md file, so that they are credited for their contribution. See #25967 Co-authored-by: andreiborza <168741329+andreiborza@users.noreply.github.com>
…26165) Router integrations set `url.full` with `getAbsoluteUrl`, which resolved a path like `//foo/bar` as a protocol-relative URL, so the first path segment became the host (`https://foo/bar`). `getAbsoluteUrl` now treats a leading `//` as a path on the current origin, the same way #21645 fixed `//` request paths in core. This fixes every router integration that passes a pathname to the helper. The Next.js app router is the one exception: Next.js treats `router.push('//host/x')` as an external URL and navigates to that host, so the app router instrumentation keeps the protocol-relative meaning there. With a basePath, Next.js makes it a local path, and the SDK does the same. Closes #26157 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…step attempt (#26161) Since #21025, `instrumentWorkflowWithSentry` only captures a step error once retries are exhausted. A `NonRetryableError` ends the instance on an earlier attempt, so it was never reported. We now also capture errors the Workflows engine treats as non-retryable, using the engine's own rule (`name === 'NonRetryableError'` or a message starting with `NonRetryableError`) so we don't import `cloudflare:workflows` at runtime. Closes #26091 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…age_delta (#26170) ## What Bedrock Claude streams now record the final output token count from `message_delta`. ## Why The count in `message_start` is only a placeholder, so Claude stream spans showed about 1 output token. Extracted from #26118. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
… test (#26172) **Why:** `injects the release only into initial chunks` runs a full `mode: 'production'` webpack build within Vitest's default 5s timeout. On cold Node 20 runners it often goes past that, and it caused 7 of the 10 recent `CI: Build & Test` failures on `develop` I looked at (details in the issue). This gives it the same `{ timeout: 15_000 }` that the sibling `child-compiler.test.ts` already uses. As agreed in the issue, this is a first try; if it still flakes at 15s, the build itself needs a look. Locally the test passes in about 2.6–3.1s with the change (3 runs, Node 24). Closes #26169 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This PR adds the external contributor to the CHANGELOG.md file, so that they are credited for their contribution. See #26172 Co-authored-by: andreiborza <168741329+andreiborza@users.noreply.github.com>
Today our CI uses x86 runners for all our job, this PR moves a selection of our CI runners to the free ARM64 runners to reduce CI time. The jobs that are moved over were determined by doing a few benchmark runs with more details in the tables below. x86 baseline is our CI as it runs today. The ARM run then uses ARM runners as much as possible with the caveat that we cannot move node/bun/deno integration tests to ARM atm because they run SQL Server container tests that do not work on ARM (potentially something we can look into next if we go with this). Running on ARM improves many jobs a lot but is worse for browser and E2E tests, partially because of missing cache hits. That's how I ended up with the "hybrid" configuration that basically takes best of both worlds. | Configuration | Required CI time* | vs x86 | |---|---:|---:| | [x86 baseline](https://github.com/getsentry/sentry-javascript/actions/runs/41988650376) | 10m42s | — | | [ARM trial](https://github.com/getsentry/sentry-javascript/actions/runs/41990016190) | 9m47s | 55s faster (8.6%) | | [Hybrid](https://github.com/getsentry/sentry-javascript/actions/runs/41994627106) | **9m31s** | **71s faster (11.1%)** | In the table below you can see in more detail how the job timings changed between the configurations for the latest test run: | Job / group | x86 | ARM trial | |---|---:|---:| | **Required CI completion*** | **10m42s** | **9m47s** | | Build | 1m58s | 1m54s | | Build bundles | 2m52s | 2m21s | | Build tarballs | 3m59s | 2m56s | | Lint | 2m19s | 1m40s | | Size check | 2m22s | 1m29s | | Node unit tests | 4m28s | 3m14s | | Bun unit tests | ~56s | 47s | | Deno unit tests | 1m18s | 1m02s | | Bundler integration | 1m44s | 1m41s | | Browser unit tests | 2m44s | 2m52s | | Browser Playwright | 2m40s | 3m47s | | Browser loader | 1m22s | 1m48s | | E2E | 1m07s | 1m35s | | Node integration† | 4m54s | 4m46s | | Bun integration† | 4m31s | 4m48s | | Deno integration† | 4m15s | 4m39s | \* Excludes initial queueing and optional jobs. Each run had one required-test failure; ARM browser caches were cold. † These integration jobs stayed on x86 in both runs. --------- Co-authored-by: OpenAI Codex <codex@openai.com>
|
|
||
| ### Other Changes | ||
|
|
||
| - feat(deps): Bump ws from 8.18.0 to 8.22.2 ([#26242](https://github.com/getsentry/sentry-javascript/pull/26242)) |
b1ec779 to
6b0577f
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 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 6b0577f. Configure here.
**Why:** Removing rimraf in #26219 left two unused lockfile entries that pnpm prunes during installation, causing develop's lockfile stability check to fail. Commit the generated cleanup to restore CI. Co-authored-by: OpenAI Codex <codex@openai.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
06aaac4 to
7be0b7a
Compare
Optional E2E testsSome optional checks were not successful. They do not block the merge. 6 not successful, 51 successful. See the run.
Successful checks
|
size-limit report 📦Compared: 580e95a (PR test merge using master at 3f2b556) Against: eadbabb (master) · base run #65073
|

No description provided.