Skip to content

meta(changelog): Update changelog for 11.3.0 - #24987

Merged
chargome merged 58 commits into
masterfrom
prepare-release/11.3.0
Oct 2, 2026
Merged

chargome merged 58 commits into
masterfrom
prepare-release/11.3.0

Conversation

@chargome

@chargome chargome commented Oct 2, 2026

Copy link
Copy Markdown
Member

No description provided.

mydea and others added 30 commits October 1, 2026 12:45
…#24923)

The WebSocket e2e tests in the Cloudflare test apps waited for any error
event. Playwright runs these files with parallel workers, so the waiter
could pick up the error from the RPC or Durable Object fetch test
instead. The test then failed on the message, and `socket.close()` threw
because the socket hadn't opened yet. Each WebSocket test now waits for
its own error message.

Same fix applied to `cloudflare-workers`, `cloudflare-workers-static`
and `cloudflare-workersentrypoint`, which share this test.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Returning the incoming config from the source-map hook causes Vite to
concatenate existing arrays with themselves. With Nitro, duplicated
asset processing can embed module source instead of the original file
content. Return only the source-map setting, following the existing
SolidStart implementation.

Fixes #23753

---------

Co-authored-by: GPT-6 <codex@openai.com>
Apply the same config-hook fix as #24929 to React Router. Returning the
incoming config causes Vite to concatenate existing arrays with
themselves, potentially duplicating build plugins. Return only the
source-map setting instead.

---------

Co-authored-by: GPT-6 <codex@openai.com>
[Gitflow] Merge master into develop
…#23551)

Adds the route provider API to core so framework SDKs can register how
to resolve a URL to a parameterized route, and wires up
`bfcacheMetricsIntegration` as the first consumer since that is where
the fragmentation currently produces a raw URL on a metric dimension.

`bfcacheMetrics` keeps its pathname fallback, so nothing changes until a
provider is registered.

closes #23556
Registers a route provider for Next.js from the manifests already
injected at build time, covering both the App Router and the Pages
Router.

Registered from `init()` rather than from `browserTracingIntegration`,
which is the point of the change: both manifests are on the global
object before `Sentry.init` runs, so nothing has to wait for a router or
for tracing. `bfcacheMetricsIntegration` now resolves a parameterized
route with `browserTracingIntegration` absent entirely, and the same
will hold for web vitals and interactions as they move over.

The two manifests want the pathname differently, since App Router routes
are generated with `basePath` baked in while Next strips it internally
for the Pages Router, so the provider normalizes per manifest.

Part of #23556
Registers a route provider for Remix from the route manifest the Vite
plugin already injects at build time.

`maybeParameterizeRemixRoute` was already a pure matcher over that
manifest, it was just only reachable from the pageload and navigation
instrumentation. Registered from `init()` rather than a tracing
integration, so route parameterization no longer depends on tracing
being enabled.

Same shape as #23552, and simpler: Remix has one manifest and no
`basePath` asymmetry.

Part of #23556
Registers a route provider for Astro from the `sentry-route-name` meta
tag the middleware already injects into every rendered document.

Registered from `init()` rather than the tracing integration, so route
parameterization no longer depends on tracing being enabled.

Unlike the Next.js and Remix providers this is not a matcher. The
document only ever describes the page it rendered, so a URL other than
the current one resolves to `undefined` rather than a guess. That guard
is also what stops a navigation being named after the route it is
leaving.

I checked the soft-navigation behaviour against Astro 5.18 with a
throwaway app rather than assuming it. `ClientRouter` swaps the tag
during `astro:after-swap`, at the same moment `location` changes, and
does not accumulate duplicates, so reading it per call stays correct
across client-side navigations and back/forward. It is only stale
*during* a navigation, before the swap, which the current-path guard
already excludes.

Part of #23556
Registers a route provider for Vue so route parameterization works
without tracing and without passing `router` to
`browserTracingIntegration`.

The provider is registered in `vueIntegration`'s `setup`, so it picks up
`app` whether it's passed to `init` or to the integration; a
`routeProvider` passed to `init` takes precedence. On Vue 3 the router
is read off `app.config.globalProperties.$router` on each call, since
`app.use(router)` may run either side of `Sentry.init()`. Vue 2 only
exposes the router on instances, so a `beforeCreate` mixin picks it up
from the root `new Vue({ router })`. Until that instance exists nothing
resolves, so the Vue 2 pageload span keeps the raw URL.

`resolve()` matches the router's own location, not the browser's, so
URLs are converted first: the path comes from the hash in hash mode, and
the router's `base` is stripped otherwise (Vue Router 3 and 4).

Returns the matched path rather than `route.name`, even under
`routeLabel: 'name'`. Callers set `url.template` from this, and a route
name is an identifier, not a template.

The factory is exported as `_INTERNAL_createVueRouteProvider` for Nuxt;
it isn't meant for users.

Part of #23556
Registers a route provider for Nuxt in the client plugin, outside the
`__SENTRY_TRACING__` guard.

Nuxt installs the router before its plugins run, so the plugin can read
it straight off `nuxtApp` rather than waiting for a Vue app the way
`@sentry/vue` has to. Reuses `createVueRouteProvider` from #23553's
successor rather than reimplementing the vue-router resolve handling.

Because it sits outside the tracing guard, route parameterization
survives when tracing is tree-shaken away.

Part of #23556
…24821)

A `"use cache"` hit tells you nothing about where the value came from.
This PR connects the two traces: a `cache.get` hit span now carries a
span link (`sentry.link.type: 'cache_origin'`) to the `cache.put` span
of the request that filled the entry.

This covers cached functions, components, and layouts that Next reads
through its cache handlers at request time. That's `"use cache"` in
route handlers and in dynamically rendered pages.


Successful cache fills are remembered in a bounded per-process `LRUMap`.
When the cache origin is unknown, the hit span gets no link.


Closes #24294
Linear:
https://linear.app/getsentry/issue/JS-3656/link-cache-hits-to-the-trace-that-filled-the-cache-entry
…nds to Sentry (#24816)

test(cloudflare): Add Flue E2E test that deploys a real Worker and sends to Sentry
#24829)

fix(cloudflare): Don't treat DO constructor work as incoming RPC calls
Updating tests to Effect v4 and our dev dependencies of the SDK. The
`peerDependency` was updated to v4 stable as the fiber changed. We would
have needed a workaround to also support beta and rc versions, which is
IMO not worth it just for supporting a beta

Breaking because we had to change where the `currentSpan` is coming
from. With that we don't support beta versions anymore
…lds (#24919)

Rolldown calls `renderChunk` before file names and hashes are final, so
the chunk code still holds hash placeholders. Deriving the debug ID from
that code made unchanged chunks get a different ID, and so a different
content hash, on every build.

For Rolldown the plugin now injects a fixed-width placeholder in
`renderChunk` and swaps in the real ID in a `pre` `generateBundle` hook,
derived from the final chunk code. The swap runs before other plugins'
`generateBundle` hooks, so integrity hashes see the final code. Rollup
builds keep the existing content-based IDs.

The Nuxt source map e2e check now skips chunks that Rolldown emits
without a source map (Vue's export helper). It passed before only
because the server build held an identical chunk with the same
content-based ID.

This continues #23665 by @chen-anders with the original commits kept.
The Vite source map re-stamping from that PR is split out into its own
PR. Every Rolldown and Vite 8 build gets new debug IDs for unchanged
chunks after upgrading; this is harmless.

Fixes #23448

---------

Co-authored-by: Anders Chen <anders@wistia.com>
Co-authored-by: OpenAI Codex <codex@openai.com>
)

Remix 3 has no bundler, so the browser gets whatever module graph the
client entry reaches and nothing can be eliminated. The entry is a named
export list rather than a wildcard re-export, and it is bundled once at
publish time. Unbundled that costs an app 255 requests and about 364 KB
gzipped; bundled it is 2 requests and 54 KB. The size budget is here
rather than in a later pull request because one wildcard re-export
silently undoes all of it.

Navigation tracing is the SDK's own, because `remix/ui` intercepts links
through the Navigation API and never touches History, so the upstream
handler would emit nothing. Page loads are ordinary document loads and
stay upstream.

Client error capture is a separate pull request.

Part of #24665

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…eload rewrite (#24920)

With `sourcemaps.disable: 'disable-upload'`, Vite builds shipped some
source maps without a debug ID. Vite's own `generateBundle` step
rewrites every chunk with a dynamic import to add module preloading,
regenerates that chunk's source map and overwrites the `.map` asset.
This runs after the Sentry plugin's `pre` hook stamped the map, so the
stamp is lost. Sentry then cannot match the map to the chunk.

`sentryVitePlugin()` now also returns a `post` plugin that re-stamps the
maps in a `post` `generateBundle` hook. It leaves the chunk code alone,
so file hashes stay valid. Reproduced on Vite 7.3 and 8.0, and the new
integration fixture fails without the fix.

Split out of #23665 by @chen-anders.

---------

Co-authored-by: Anders Chen <anders@wistia.com>
… sent (#24655)

The Durable Object SQL instrumentation sanitized and summarized each
query, also when the span could not be sent: tracing not configured, or
an unsampled parent. On SQL-heavy Durable Objects, this was a large CPU
cost with `tracesSampleRate: 0`.

In these cases, the query is not sanitized now. `startSpan` still runs
with the name `exec` and the static attributes, so an unsampled span
still records its `sample_rate` outcome. A query that can target a `cf_`
table takes the full path, because an internal query must not start a
span.

Under span streaming with an unsampled parent, an `ignoreSpans` rule
that matches the span name or `db.query.text` does not match now. Thus
the dropped span is reported as `sample_rate`, not `ignored`. The number
of dropped spans does not change. Rules that match `op: 'db.query'` are
not affected.

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: isaacs <i@izs.me>
Deno integration suites still pin static tracing and miss the SDK's
default span-streaming behavior. Exercise streaming with span-envelope
capture and streamed span assertions, while retaining the GraphQL suite
as static lifecycle coverage.

Fixes #24004
Fixes #24133

Co-authored-by: GPT-6 <codex@openai.com>
…24928)

Follow up on #24783 and #24902: align the shared helper name with
`wrapStreamResult` and pin the OpenAI and Anthropic APIPromise source
links to immutable commits.

Co-authored-by: GPT-6 <codex@openai.com>
…s of case (#24855)

`messages.stream()` calls the instrumented `messages.create({ stream:
true })` underneath and tags that call with a helper-method header. The
integration uses that header to skip the nested `create`, so a streamed
message gets one span.

The SDK sent the header as `X-Stainless-Helper-Method` up to 0.105 and
as lowercase `x-stainless-helper-method` since 0.106. The check compared
the exact casing, so on a current SDK every `messages.stream()` produced
two nested `gen_ai.chat` spans, both with the full attributes. Header
names are case-insensitive, so the check now matches without regard to
case.

**Second commit, from review.** Matching the header alone was not
enough: `beta.messages.stream()` and the streaming tool runner tag their
internal `create` with the same header, but only the non-beta helper is
on the `messages-stream` channel, so nothing covers them and skipping
left them with no span at all. The skip now only applies while a
stream-helper span this integration opened is the active span. The
regular helper is still deduped; the beta helper and the tool runner
keep their span.

**Found by** the send-to-sentry e2e app for Anthropic (#24748, PR
#24856) in its `latest` variant. On 0.63 the stream helper gives one
span; on 0.129 it gave two.

**Tests.**
- `suites/tracing/anthropic/v0.129` (Node), pinned to that SDK version
the way the openai v7 suite is: one span for `messages.stream()`, and
one span each for `beta.messages.stream()` and the eager streaming tool
runner. The beta scenario is from isaacs' review.
- `suites/tracing/anthropic-ai-stream-helper` (Cloudflare), built
through the Sentry Vite plugin so the calls go through the channel
integration on workerd, where the active span is the core span rather
than an OpenTelemetry one: one span for the regular helper, one for the
beta helper.

Each suite fails without its half of the fix and passes with it. The
existing Anthropic suites on 0.63 still pass.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: isaacs <i@izs.me>
An e2e app that uses the Anthropic integration the way a user does and
sends the data to a real Sentry project, per #24748. Same shape as the
OpenAI one in #24824.

**Stacked on #24855.** The `latest` variant needs that fix; this PR
targets its branch and retargets to `develop` once it merges.

**The app.** A plain `Sentry.init` on an express app, preloaded with
`node --import`, no tunnel. The stock `@anthropic-ai/sdk` client talks
to OpenRouter's Anthropic-compatible endpoint. Four routes make one real
request each: a message, a streamed message, one through the
`messages.stream()` helper, and a forced tool use.

**The tests.** Each one reads the request's `gen_ai.chat` 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 helper test also checks there is exactly one
`gen_ai.chat` span, which is what caught the duplicate fixed in #24855.
`@anthropic-ai/sdk` is pinned to 0.63.0, the version the integration
suite uses, and a `(latest)` variant runs the same tests against
`@anthropic-ai/sdk@latest`. Both are optional, like the other
send-to-sentry apps.

Closes #24748

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Jan Peer Stöcklmair <jan.peer@sentry.io>
The `remix/ui` runtime sends every render, scheduler, frame and
hydration error to the event target `run()` returns, and dispatching an
event does not rethrow. So `window.onerror` and `unhandledrejection`
never see them, and the default browser integrations report nothing from
the component layer. Removing the listener added here makes the new e2e
test fail.


Costs 0.27 KB gzipped in the client bundle, inside the existing budget.

Fixes #24665

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Remix 3 has no build step, so there is no bundler plugin to inject debug
IDs. The asset server compiles each module on request, and this patches
`createAssetServer` to add a loader that injects the debug ID snippet
into every compiled module. The ID is a hash of the compiled source and
the module URL, so it is stable across requests and the source map
upload can arrive at the same ID in another process.

The minifier drops comments and the asset server rebuilds source maps
after the loaders ran. So the `//# debugId=` comment and the `debugId`
field in the map, which is what `sentry-cli` reads, are added to the
served response instead.

Source maps follow the other meta framework SDKs. Left out, they are
generated but hidden: modules do not reference them and `.map` requests
are not served. `sourceMaps: false` keeps them off, with a warning that
stack traces stay minified.

`getDebugId` and the snippet mirror `@sentry/bundler-plugins/core`
rather than importing it, because that entry loads the whole build
plugin into the server.

Fixes #24667

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Covers the error paths the router middleware alone does not see, and
stops reporting things that are not faults.

`createRequestListener` in `@remix-run/node-fetch-server` is patched to
install an `onError` that chains to the app's own. This is the only hook
that covers an app whose fetch handler is not a router. It needs no
abort guard: the listener checks `isRequestAbortError` itself and
returns before calling `onError`.

The middleware captures too, so an event carries the route and request
already on the scope. That path does need the abort guard, because
`raceRequestAbort` rejects with `signal.reason` when the client
disconnects. Without it every user navigating away mid request creates
an issue. Removing the guard makes the new e2e test fail.

`shouldHandleError` follows `@sentry/hono`: skip 3xx and 4xx errors
carrying a numeric `status`, capture the rest.

Fixes #24664

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…pans (#23900)

`@sentry/effect` parented every Effect span on the active Sentry span. A
`Tracer.ExternalSpan` parent was dropped, so a persisted trace continued
with `Tracer.externalSpan` started a disconnected trace, and a `root:
true` span or a span leaked from another fiber through the async context
could become the parent of an unrelated span. On the server, every
parentless span also shared the process-wide propagation context, so a
long-lived process put all of its work into one trace.

- A parentless span only nests under a foreign active Sentry span (an
`http.server` span from the Node SDK, a pageload), never under a span
this tracer created.
- The server tracer starts a new trace for every parentless span, unless
the user set up the current scope (`continueTrace`, `withScope`, an
isolation scope). The client tracer keeps parentless spans in the page
trace.
- An external parent is ignored by default, and the span nests where
Effect would have put it without the `parent` option: under the fiber's
current span, or parentless.
- The new `SentryEffectExternalSpanLayer` opts into continuing external
parents: the span becomes a new root span with the external span as
`parent_span_id`. No dynamic sampling context is frozen, so the SDK
builds one from the client. Next to the tracer layer it applies to the
whole runtime, with `Effect.provide` to a single effect only there.

### Decisions

**External parents are opt-in.** A `Tracer.externalSpan` parent bridges
a trace the SDK did not start, for example an OpenTelemetry span of
another app in the same process, or trace state persisted with a queue
message. Joining such a trace silently would re-parent spans into a
trace the SDK cannot vouch for, so the user adds the layer to ask for
it. Incoming trace headers on the Effect HTTP server are out of scope
here and get their own PR.

**The opt-in is a layer, not a second tracer.** Two layers that set the
tracer race inside `Layer.mergeAll`, and a wrapping tracer only sees the
Sentry one when nested with `Layer.provide`. A flag in the fiber context
composes in `Layer.mergeAll` like `Layer.setTracer` does, and also works
per effect. It is a plain service in both Effect versions, because v4
has no `FiberRef` and v3 has no `Context.Reference`.

**How the tracer reads the flag.** Effect's `span` hook gets no fiber in
either version, only the span's own context or annotations. The
`context` hook does get the fiber and wraps every operation the fiber
evaluates, and `span` runs synchronously inside it, so the hook keeps
the fiber in a module variable for that extent, the same way it already
sets the active Sentry span there. The flag is read only when an
external parent shows up.

These fixes apply to both trace lifecycles. One related limitation stays
and is specific to `traceLifecycle: 'static'`: a child span that ends
after its root span is dropped with the transaction. Long-running Effect
fibers, such as a background agent that outlives the request that
started it, lose those children unless `traceLifecycle: 'stream'` is
used, which sends every span on its own end and is the default since
v11.

The effect-3-node and effect-4-node e2e apps cover a
`Tracer.externalSpan` parent continued through the layer and a `root:
true` span inside a request.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…24896)

The continuous profiler sent `profile_chunk` envelopes straight to the
transport, so the `beforeEnvelope` hook never ran for them. It now uses
`client.sendEnvelope()`, as the browser `UIProfiler` does.

- Ref. getsentry/sentry-electron#1445
…sts (#24957)

The send-to-sentry E2E tests often fail with `429 Too Many Requests`
("Limit is 40 requests in 1 seconds"). Sentry rate limits GET requests
per token owner, and every endpoint used here shares the default bucket.
So all E2E jobs across all PRs share one 40 req/s budget.

Most of the load came from `sentry trace view --json`. The `--json` flag
makes the CLI fetch details for every span, one request each (15 at a
time), on top of a project lookup and the trace request. Every 5s poll
turned into dozens of requests. `fetchTrace` now calls the trace
endpoint directly through `sentry api`, which is one request per poll.
The tests only read fields that the raw trace response already includes
(`event_id`, `parent_span_id`, `event_type`, `op`, `description`,
`children`, `errors`, `occurrences`).

All the polling helpers now also treat a 429 as "not there yet" and keep
polling until the existing timeout, instead of failing on the first
rate-limited response.

<!-- junior-request-attribution:start -->
via **Jan Peer Stöcklmair**.
<!-- junior-request-attribution:end -->

<!-- junior-session-footer:start -->
<!-- junior-conversation-id:slack%3ACUHS29QJ0%3A1790866806.848059 -->

--

[View Junior
Session](https://junior-prod.sentry.dev/conversations/slack%3ACUHS29QJ0%3A1790866806.848059)
[[Sentry]](https://sentry.sentry.io/explore/conversations/slack%3ACUHS29QJ0%3A1790866806.848059/?project=4510944073809921)

<!-- junior-session-footer:end -->

Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
Co-authored-by: Jan Peer Stöcklmair <jan.peer@sentry.io>
#24520)

On Bun and Deno, `init()` warned when Sentry was already initialized but
then initialized again, replacing the client. Anything buffered on the
first client was dropped and its integrations stayed installed against
it.

Both now keep the warning and return the existing client, as the Node
entry already does. Node's behavior is unchanged (it only logs in debug
mode, since it is initialized from an instrument file); Cloudflare
initializes per request through `withSentry` and is not affected.

Closes #24049

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
dependabot Bot and others added 10 commits October 2, 2026 11:59
Bumps [getsentry/craft](https://github.com/getsentry/craft) from 2.30.1
to 2.31.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/getsentry/craft/releases">getsentry/craft's
releases</a>.</em></p>
<blockquote>
<h2>2.31.2</h2>
<h3>Bug Fixes 🐛</h3>
<ul>
<li>(deps) Remediate open security alerts by <a
href="https://github.com/BYK"><code>@​BYK</code></a> in <a
href="https://redirect.github.com/getsentry/craft/pull/881">#881</a></li>
<li>(github) Filter artifacts by name when fetching revision artifact by
<a href="https://github.com/itaybre"><code>@​itaybre</code></a> in <a
href="https://redirect.github.com/getsentry/craft/pull/880">#880</a></li>
</ul>
<h2>2.31.1</h2>
<h3>Bug Fixes 🐛</h3>
<ul>
<li>(npm) Show publish stderr at info level by <a
href="https://github.com/sentry-junior"><code>@​sentry-junior</code></a>
in <a
href="https://redirect.github.com/getsentry/craft/pull/877">#877</a></li>
</ul>
<h3>Internal Changes 🔧</h3>
<h4>Deps</h4>
<ul>
<li>Bump sharp from 0.35.0 to 0.35.4 in /docs by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/getsentry/craft/pull/874">#874</a></li>
<li>Bump astro from 7.1.4 to 7.2.8 in /docs by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/getsentry/craft/pull/873">#873</a></li>
</ul>
<h4>Deps Dev</h4>
<ul>
<li>Bump vitest from 4.1.8 to 4.1.11 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/getsentry/craft/pull/875">#875</a></li>
<li>Bump js-yaml from 4.3.1 to 4.3.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/getsentry/craft/pull/876">#876</a></li>
</ul>
<h2>2.31.0</h2>
<h3>New Features ✨</h3>
<ul>
<li>(config) Top-level workspaces schema + --workspace selector by <a
href="https://github.com/BYK"><code>@​BYK</code></a> in <a
href="https://redirect.github.com/getsentry/craft/pull/848">#848</a></li>
<li>Propagate release workspaces by <a
href="https://github.com/BYK"><code>@​BYK</code></a> in <a
href="https://redirect.github.com/getsentry/craft/pull/872">#872</a></li>
</ul>
<h3>Bug Fixes 🐛</h3>
<ul>
<li>(git) Prevent fatal error for missing 'origin' remote by <a
href="https://github.com/sentry"><code>@​sentry</code></a> in <a
href="https://redirect.github.com/getsentry/craft/pull/871">#871</a></li>
<li>(registry) Retry registry push with backoff on concurrent updates by
<a
href="https://github.com/jared-outpost"><code>@​jared-outpost</code></a>
in <a
href="https://redirect.github.com/getsentry/craft/pull/870">#870</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/getsentry/craft/blob/master/CHANGELOG.md">getsentry/craft's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h2>2.31.2</h2>
<h3>Bug Fixes 🐛</h3>
<ul>
<li>(deps) Remediate open security alerts by <a
href="https://github.com/BYK"><code>@​BYK</code></a> in <a
href="https://redirect.github.com/getsentry/craft/pull/881">#881</a></li>
<li>(github) Filter artifacts by name when fetching revision artifact by
<a href="https://github.com/itaybre"><code>@​itaybre</code></a> in <a
href="https://redirect.github.com/getsentry/craft/pull/880">#880</a></li>
</ul>
<h2>2.31.1</h2>
<h3>Bug Fixes 🐛</h3>
<ul>
<li>(npm) Show publish stderr at info level by <a
href="https://github.com/sentry-junior"><code>@​sentry-junior</code></a>
in <a
href="https://redirect.github.com/getsentry/craft/pull/877">#877</a></li>
</ul>
<h3>Internal Changes 🔧</h3>
<h4>Deps</h4>
<ul>
<li>Bump sharp from 0.35.0 to 0.35.4 in /docs by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/getsentry/craft/pull/874">#874</a></li>
<li>Bump astro from 7.1.4 to 7.2.8 in /docs by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/getsentry/craft/pull/873">#873</a></li>
</ul>
<h4>Deps Dev</h4>
<ul>
<li>Bump vitest from 4.1.8 to 4.1.11 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/getsentry/craft/pull/875">#875</a></li>
<li>Bump js-yaml from 4.3.1 to 4.3.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/getsentry/craft/pull/876">#876</a></li>
</ul>
<h2>2.31.0</h2>
<h3>New Features ✨</h3>
<ul>
<li>(config) Top-level workspaces schema + --workspace selector by <a
href="https://github.com/BYK"><code>@​BYK</code></a> in <a
href="https://redirect.github.com/getsentry/craft/pull/848">#848</a></li>
<li>Propagate release workspaces by <a
href="https://github.com/BYK"><code>@​BYK</code></a> in <a
href="https://redirect.github.com/getsentry/craft/pull/872">#872</a></li>
</ul>
<h3>Bug Fixes 🐛</h3>
<ul>
<li>(git) Prevent fatal error for missing 'origin' remote by <a
href="https://github.com/sentry"><code>@​sentry</code></a> in <a
href="https://redirect.github.com/getsentry/craft/pull/871">#871</a></li>
<li>(registry) Retry registry push with backoff on concurrent updates by
<a
href="https://github.com/jared-outpost"><code>@​jared-outpost</code></a>
in <a
href="https://redirect.github.com/getsentry/craft/pull/870">#870</a></li>
</ul>
<h2>2.30.1</h2>
<h3>Bug Fixes 🐛</h3>
<ul>
<li>(vercel) Pass prebuilt output directory by <a
href="https://github.com/BYK"><code>@​BYK</code></a> in <a
href="https://redirect.github.com/getsentry/craft/pull/868">#868</a></li>
</ul>
<h2>2.30.0</h2>
<h3>New Features ✨</h3>
<ul>
<li>(vercel) Allow project ID in target config by <a
href="https://github.com/BYK"><code>@​BYK</code></a> in <a
href="https://redirect.github.com/getsentry/craft/pull/867">#867</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/getsentry/craft/commit/25028d0646040cc0a669ae3314cbf884f4c4347a"><code>25028d0</code></a>
release: 2.31.2</li>
<li><a
href="https://github.com/getsentry/craft/commit/bba2a96b0bf69e605499c0919785f93901ae3f45"><code>bba2a96</code></a>
fix(deps): remediate open security alerts (<a
href="https://redirect.github.com/getsentry/craft/issues/881">#881</a>)</li>
<li><a
href="https://github.com/getsentry/craft/commit/7137f2012aeb36523e02cd55b9aebf02082dfb97"><code>7137f20</code></a>
fix(github): Filter artifacts by name when fetching revision artifact
(<a
href="https://redirect.github.com/getsentry/craft/issues/880">#880</a>)</li>
<li><a
href="https://github.com/getsentry/craft/commit/960a1c727b6b5dc680c450a029888159270b6d78"><code>960a1c7</code></a>
meta: Bump new development version</li>
<li><a
href="https://github.com/getsentry/craft/commit/7dab3b4c1734cef9edffba2d4bd291da050f8681"><code>7dab3b4</code></a>
Merge remote-tracking branch 'remotes/origin/release/2.31.1'</li>
<li><a
href="https://github.com/getsentry/craft/commit/b5451aa5604f399ebaef98c0850bece7d062e288"><code>b5451aa</code></a>
release: 2.31.1</li>
<li><a
href="https://github.com/getsentry/craft/commit/05953a057618ec42400d98d513b32afc8b9bdbab"><code>05953a0</code></a>
fix(npm): Show publish stderr at info level (<a
href="https://redirect.github.com/getsentry/craft/issues/877">#877</a>)</li>
<li><a
href="https://github.com/getsentry/craft/commit/c17a2788c42da14529c3c96fea2dd7c25260025e"><code>c17a278</code></a>
build(deps-dev): bump vitest from 4.1.8 to 4.1.11 (<a
href="https://redirect.github.com/getsentry/craft/issues/875">#875</a>)</li>
<li><a
href="https://github.com/getsentry/craft/commit/a2e058974cfd81eeee11cd8f9443895541d44f8b"><code>a2e0589</code></a>
build(deps): bump sharp from 0.35.0 to 0.35.4 in /docs (<a
href="https://redirect.github.com/getsentry/craft/issues/874">#874</a>)</li>
<li><a
href="https://github.com/getsentry/craft/commit/12f3b0242a008b6a7294a2cc863207d5d3b17df7"><code>12f3b02</code></a>
build(deps-dev): bump js-yaml from 4.3.1 to 4.3.2 (<a
href="https://redirect.github.com/getsentry/craft/issues/876">#876</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/getsentry/craft/compare/cd1e8294061fd970b40d98b77aaa109cb1e00e78...25028d0646040cc0a669ae3314cbf884f4c4347a">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=getsentry/craft&package-manager=github_actions&previous-version=2.30.1&new-version=2.31.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Uses `SENTRY_EXCLUSIVE_TIME` from `@sentry/conventions/attributes` in
span serialization, transaction conversion, and web-vital spans.
Deprecates the existing core constant while preserving its public export
and the identical `sentry.exclusive_time` key; calculations, values, and
serialization behavior remain unchanged.

Part of #24961 / [JS-3868](https://linear.app/getsentry/issue/JS-3868).

Co-authored-by: GPT-6 <codex@openai.com>
Uses `CACHE_HIT`, `CACHE_KEY`, and `CACHE_ITEM_SIZE` from
`@sentry/conventions/attributes`. Deprecates the existing core constants
while preserving their public exports and identical attribute keys;
emitted values and cache behavior remain unchanged.

Part of #24961 / [JS-3868](https://linear.app/getsentry/issue/JS-3868).

Co-authored-by: GPT-6 <codex@openai.com>
Uses `USER_ID`, `USER_EMAIL`, `USER_IP_ADDRESS`, and `USER_NAME` from
`@sentry/conventions/attributes`. Deprecates the existing core constants
while preserving their public exports and identical attribute keys;
emitted values and data-collection behavior remain unchanged.
`USER_NAME` still maps the existing username to `user.name`.

Part of #24961 / [JS-3868](https://linear.app/getsentry/issue/JS-3868).

Co-authored-by: GPT-6 <codex@openai.com>
Uses `HTTP_REQUEST_METHOD` from `@sentry/conventions/attributes`.
Deprecates the existing core constant while preserving its public export
and identical `http.request.method` key; emitted values, method
normalization, defaults, and the GraphQL fallback to `http.method`
remain unchanged.

Part of #24961 / [JS-3868](https://linear.app/getsentry/issue/JS-3868).

Co-authored-by: GPT-6 <codex@openai.com>
…atus is set (#24924)

Since v11, `fastifyIntegration` always registers an `onError` hook
(#23460). Fastify runs `onError` hooks before it applies the error's
status to the reply, so for errors raised outside the route handler,
such as a request body that fails to parse
(`FST_ERR_CTP_EMPTY_JSON_BODY`, `FST_ERR_CTP_INVALID_JSON_BODY`),
`defaultShouldHandleError` still reads `reply.statusCode === 200` and
captures what is sent to the client as a 400. #18418 fixed the same
symptom for route handler errors upstream in Fastify 5.7.0, but only on
the diagnostics channel path.

When `reply.statusCode` is still the default 200, the default
`shouldHandleError` now resolves the status the same way Fastify's
`setErrorStatusCode` does: the error's `statusCode` or `status` if it is
at least 400, otherwise 500. This predicts the status Fastify is about
to send, and errors without a status still count as 500, so they are
still captured. A status already set on the reply takes precedence, as
before.

A custom `shouldHandleError` still receives `reply.statusCode === 200`
on this path. I left that alone, since changing what callbacks receive
is a separate decision.

Fixes #24926

---------

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 #24924

Co-authored-by: nicohrubec <29484629+nicohrubec@users.noreply.github.com>
Uses `SENTRY_PROFILE_ID` from `@sentry/conventions/attributes`.
Deprecates the existing core constant while preserving its public export
and identical `sentry.profile_id` key; emitted values and
span/transaction serialization remain unchanged.

Part of #24961 / [JS-3868](https://linear.app/getsentry/issue/JS-3868).

Co-authored-by: GPT-6 <codex@openai.com>
Remix 3 has no build step and no output directory, so there is nothing
on disk for a source map upload to read.

`emitAssets()` rebuilds the output by driving the app's own asset
server: `getPreloads()` forces the browser module graph, and each
compiled module and its map is written out. The debug IDs are hashed
from the compiled source, so the emitted IDs match what the running
server serves.

The instrumented server hides source maps by default, so the emitter
reads them through the server's own fetch, which the stamping wrapper
now keeps reachable.

`sentry-remix-v3-upload-sourcemaps` is a separate bin from the Remix 2
`sentry-upload-sourcemaps`. It must run under `--import
@sentry/remix/v3/node`, which provides the TypeScript loader and patches
the asset server. Without it the emitted modules carry no debug IDs, so
the command fails on that rather than uploading an unusable set. This is
far from optimal but until we found a better solution this works.

The e2e test runs the bin against the app and checks that every module
has a map, each pair shares a debug ID, and the emitted entry's ID
equals the served one. It uses `--dry-run`: the CLI needs authentication
even for `inject`, so the upload itself is verified separately in
#24685.

Fixes #24678

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Uses `SENTRY_RELEASE`, `SENTRY_ENVIRONMENT`, and
`SENTRY_SDK_INTEGRATIONS` from `@sentry/conventions/attributes`.
Deprecates the existing core constants while preserving their public
exports and identical attribute keys; emitted values, defaults, and
serialization remain unchanged.

Part of #24961 / [JS-3868](https://linear.app/getsentry/issue/JS-3868).

Co-authored-by: GPT-6 <codex@openai.com>
@chargome chargome self-assigned this Oct 2, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chargome
chargome force-pushed the prepare-release/11.3.0 branch from f086657 to 1c7308d Compare October 2, 2026 11:58
@chargome
chargome marked this pull request as ready for review October 2, 2026 12:00
@chargome
chargome requested review from a team as code owners October 2, 2026 12:00
@chargome
chargome requested review from Lms24, andreiborza, isaacs, logaretm, nicohrubec and s1gr1d and removed request for a team October 2, 2026 12:00
@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

⚠️ Warning: Base artifact is not the latest one, because the latest workflow run is not done yet. This may lead to incorrect results. Try to re-run all tests to get up to date results.

Path Size % Change Change
@sentry/browser 29.52 kB +0.52% +152 B 🔺
@sentry/browser - with treeshaking flags 27.68 kB +0.13% +34 B 🔺
@sentry/browser - with treeshaking flags tracing without tracing 27.57 kB +0.12% +32 B 🔺
@sentry/browser (incl. Tracing) 51.45 kB +0.28% +141 B 🔺
@sentry/browser (incl. Tracing + Span Streaming) 51.46 kB +0.29% +144 B 🔺
@sentry/browser (incl. Tracing, Profiling) 54.46 kB +0.28% +151 B 🔺
@sentry/browser (incl. Tracing, Replay) 91.04 kB +0.17% +152 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 80.03 kB +0.05% +34 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas) 95.74 kB +0.17% +155 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback) 108.71 kB +0.14% +142 B 🔺
@sentry/browser (incl. Feedback) 47.04 kB +0.34% +155 B 🔺
@sentry/browser (incl. sendFeedback) 34.57 kB +0.43% +146 B 🔺
@sentry/browser (incl. FeedbackAsync) 39.68 kB +0.36% +140 B 🔺
@sentry/browser (incl. Metrics) 30.54 kB +0.54% +161 B 🔺
@sentry/browser (incl. Logs) 30.82 kB +0.53% +162 B 🔺
@sentry/browser (incl. Metrics & Logs) 31.48 kB +0.5% +154 B 🔺
@sentry/react 31.36 kB +0.53% +164 B 🔺
@sentry/react (incl. Tracing) 53.8 kB +0.25% +134 B 🔺
@sentry/vue 37.51 kB +1.66% +610 B 🔺
@sentry/vue (incl. Tracing) 54.33 kB +0.83% +446 B 🔺
@sentry/svelte 29.55 kB +0.53% +154 B 🔺
CDN Bundle 31.22 kB +0.13% +40 B 🔺
CDN Bundle (incl. Tracing) 51.98 kB +0.08% +37 B 🔺
CDN Bundle (incl. Logs, Metrics) 33.46 kB +0.1% +31 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) 53.92 kB +0.06% +29 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) 74.21 kB +0.07% +49 B 🔺
CDN Bundle (incl. Tracing, Replay) 89.56 kB +0.05% +37 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 91.53 kB +0.05% +37 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 95.72 kB +0.03% +23 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 97.71 kB +0.04% +39 B 🔺
CDN Bundle - uncompressed 92.14 kB +0.11% +95 B 🔺
CDN Bundle (incl. Tracing) - uncompressed 154.49 kB +0.04% +59 B 🔺
CDN Bundle (incl. Logs, Metrics) - uncompressed 98.71 kB +0.1% +95 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 160.45 kB +0.04% +59 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 228.28 kB +0.05% +95 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed 274.22 kB +0.03% +59 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 280.16 kB +0.03% +59 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 287.93 kB +0.03% +59 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 293.86 kB +0.03% +59 B 🔺
@sentry/nextjs (client) 56.32 kB +0.73% +407 B 🔺
@sentry/sveltekit (client) 51.87 kB +0.26% +134 B 🔺
@sentry/core/server 40.59 kB +1.5% +599 B 🔺
@sentry/core/browser 13.63 kB -0.04% -5 B 🔽
@sentry/node 144.74 kB +0.3% +429 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 83.2 kB +0.24% +191 B 🔺
@sentry/node - without tracing 93.3 kB +0.38% +350 B 🔺
@sentry/node - without channel injection 122.97 kB +0.27% +320 B 🔺
@sentry/aws-serverless 101.57 kB +0.32% +319 B 🔺
@sentry/cloudflare (withSentry) - minified 208.61 kB +0.93% +1.92 kB 🔺
@sentry/cloudflare (withSentry) 517.4 kB +0.64% +3.27 kB 🔺
@sentry/remix (Remix 3 client bundle) 55.77 kB added added

View base workflow run

@chargome
chargome merged commit 481c43c into master Oct 2, 2026
345 checks passed
@chargome
chargome deleted the prepare-release/11.3.0 branch October 2, 2026 12:33
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.