Skip to content

meta(changelog): Update changelog for 11.6.0 - #25184

Merged
JPeer264 merged 48 commits into
masterfrom
prepare-release/11.6.0
Oct 8, 2026
Merged

JPeer264 merged 48 commits into
masterfrom
prepare-release/11.6.0

Conversation

@JPeer264

@JPeer264 JPeer264 commented Oct 8, 2026

Copy link
Copy Markdown
Member

No description provided.

Lms24 and others added 30 commits October 7, 2026 12:00
makes the `no-unsafe-random-apis` rule a bit more robust. We now
catch:

- `crypto.randomUUID!()` and TS casts (`as`, `satisfies`,` <T>`)
- Optional calls: `performance?.now()`, `crypto?.randomUUID?.()`
- Calls through a global object: `globalThis.performance.now()`,
`GLOBAL_OBJ.crypto.randomUUID()`, `WINDOW.performance?.now()`

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
[Gitflow] Merge master into develop
Add Node runner equivalents of Cloudflare’s `collectStreamedSpans` and
`collectStreamedSpansUntilSegment` so tests can collect across
envelopes.

Migrate AWS, feature-flag, GrowthBook, and sampler fallback tests using
the segment helper.

Part of #24141

---------

Co-authored-by: GPT-6 <codex@openai.com>
Port the OpenAI v5/v6/v7, Azure and tool-call integration tests to the
default span-streaming lifecycle.

I know this looks huge but it really isn't. This just uses the new
`collectStreamedSpansUntilSegment` helper and that changes indentation
that's why the diff is so large mostly.

Part of #24138

---------

Co-authored-by: GPT-6 <codex@openai.com>
Run the Bedrock Converse and InvokeModel integration test with default
span streaming. Also replaces some consts with conventions equivalents.

Part of #24138

---------

Co-authored-by: GPT-6 <codex@openai.com>
Port the Anthropic integration suites to default span streaming. Remove
the redundant streaming-only test and duplicate initialization files; no
static coverage is added.

Part of #24138

---------

Co-authored-by: GPT-6 <codex@openai.com>
Port LangGraph integration tests to default span streaming and remove
the redundant streaming-only case.

Part of #24138

---------

Co-authored-by: GPT-6 <codex@openai.com>
Port Google GenAI v1 and v2 integration tests to default span streaming.
Fold the redundant streaming-only case into the PII test and remove its
initialization file. No static coverage is added.

Part of #24138

---------

Co-authored-by: GPT-6 <codex@openai.com>
Port the LangChain integration suites to default span streaming. Fold
the streaming-only and duplicate count-only cases into the retained
tests, without adding static coverage.

Part of #24138

---------

Co-authored-by: GPT-6 <codex@openai.com>
Port the Mastra integration suites to default span streaming.

Part of #24138

---------

Co-authored-by: GPT-6 <codex@openai.com>
…on state (#23315)

`instrumentLangGraph` recorded span input and output only when the graph
state uses `MessagesAnnotation`. The input read did `args[0].messages ??
[]` and the output helper returned early when `result.messages` was not
an array, so a graph on a custom state annotation produced an empty
`gen_ai.input.messages` and no `gen_ai.response.text`. No error, just an
empty `invoke_agent` span in the AI Agents view.

This keeps the `MessagesAnnotation` path unchanged. When there is no
`messages` array, it serializes the whole input and output state and
records it, wrapped as a single `{ role, content }` message so the
attribute stays a valid chat array (the convention
`extractLLMRequestAttributes` already uses in this package). A null
input (the resume case) records nothing rather than a misleading empty
array. Serialization uses core's circular-safe `stringify` so an unusual
state object cannot throw inside the span callback.

Fixes #19628

AI assistance (Claude, Anthropic) was used in developing this change.
The design, review and verification were done by the author. Verified
locally: the `@sentry/server-utils` vitest suite (335 to 339 passing),
the new tests failing before and passing after the fix, `oxlint
--type-aware`, `oxfmt --check`, `tsc` on the changed files, plus a real
Google Gemini LangGraph run showing the span input and output empty
before and populated after.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Abdelrahman Awad <abdelrahman.awad@sentry.io>
Co-authored-by: Andrei Borza <andrei.borza@sentry.io>
…ation tests (#24925)

`cache-client > cacheClient: true - dedupe drops the same error across
invocations` failed on CI on its very first request: wrangler had
reported "Ready", but the request still got 500s for the whole ~5s retry
budget in `fetchWithRetry`. wrangler printed no error for it, so it's
the known "ready but not serving yet" startup race (#20994, #22083), not
a failure in the worker.

This widens the budget to ~15s. Requests that are expected to fail
already disable retries, so the only cost is that a genuinely unexpected
500 takes longer to report, which is fine within the 60s test timeout.
The "expected to succeed" error now also includes the response body: CI
never showed what the 500 actually was, and this makes the next
occurrence diagnosable instead of us widening the window again blindly.

🤖 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 #23315

Co-authored-by: andreiborza <168741329+andreiborza@users.noreply.github.com>
This PR fixes* clock drift that occurs when devices go to sleep. After
devices sleep for a few seconds, the browser's monotonic clock (accessed
via `performance.now()`) stops counting. Once the sleep stops, the
monotonic clock resumes right where it left off before the sleep,
causing significant discrepancies between the actual time (wall clock)
and the browser's monotonic clock time. Or in other words, there are two
ways to get an absolute timestamp:

- Using the monotonic clock via `peformance.timeOrigin +
performance.now()` - has high, sub-millisecond precision and a guarantee
that there are no time jumps or adjustments. But suffers from the sleep
problem described above
- Using the wall clock via `Date.now()` - lower millisecond precision,
is known to be corrected (NTP or via users) and can even cause back
jumps. But no sleep problem.

With this fix, we make the following adjustments, to kinda get the best
of both worlds:

- Every `timestampInSecondsCall` checks the monotonic against the wall
clock. If a threshold of difference is enocuntered, it corrects the
`timeOrigin` so that we can keep using the precise monotonic clock, but
anchor its relative time to a corrected time origin.
- On every time origin correction, we remember the previous origin (up
to 30 corrections). Needed for performance entries
- Makes `browserPerformanceTimeOrigin` a time origin corrected helper
function, where you pass in a relative time that comes from monotonic
clock relative timestamps and it returns the time origin that was most
accurate at that relative time point.
- All spans and other telemetry we create from browsers
`PerformanceEntry` objects carry relative times which are completely
sleep-drift uncorrected. We use `browserPerformanceTimeOrigin` to return
a corrected time stamp so that we can create an absolute timestamp and
bring the performance entries to their respective actual time.

### FAQ

If you think this sounds complicated, I agree. So let me answer the most
obvious questions, because I asked myself these a lot, too:

**Why not just always use `Date.now()` and avoid the complicated click
drift detection and correction logic?**

The main issue with this is that we still need to rely on relative
monotonic clock timestamps for performance entries. We cannot correct
them just with `Date.now()` alone but we still need to anchor them. So
either we rely on the original `window.timeOrigin` and therefore have
all performance entry telemetry happen much "earlier" than its
surrounding telemetry relying on `Date.now()`, or we keep the time
origin correction logic. But even in the second case (where we already
pay the tax for drift detection and correction), telemetry would still
have two different anchors: `Date.now()` for regular telemetry and the
corrected time origin + monotonic time for performance entry telemetry.

Another reason is that the monotonic clock gives us sun-millisecond
precision while the wall clock stops at a millisecond resolution.

**Why the reduction from a drift detection threshold of 5 minutes to
just one second?**

Because we keep everything centered around detection and origin offset
correction, these timestamps need to be as accurate as possible. On
phones, short frequent sleeps are very likely to happen. A lot of sleeps
can accumulate until that 5 minutes threshold is reached. So it's really
important we make these timestamps as accurate as possible.

Fwiw, I reproduced this locally and the drift is already noticeable
after just a few seconds of sleep. The 5 minutes threshold was arguably
far too big beforehand.


**Is there precedence for all of this stuff?**

Somewhat, but I'd argue we're doing a bit more: OTel uses a mixture of
`Date.now()` and `performance.now`:
- Spans start at `Date.now()` and at start time, they record a
`performance.now()` timestamp. On span end, they also take
`performance.now()`, compute the diff and convert that to an end
timestamp based on the start timestamp + diff. This is neat because it
guarantees monotony in span durations. I stole this in #24903

In other places, OTel relies purely on Date.now(), and for performance
entries, they simply take uncorrected timestamps. So our fix is more
complete.

\* **So... we're good now?**

Well, not perfectly and we never will. With this choice we make another
commitment (which we already did previously in less obvious cases) to
`Date.now()`. This value can drift as well, just not for sleeps:

- NTP adjustments: Can make hard correction of the wall clock, or make
the clock tick just a bit faster or slower until the device wall clock
synced with the network time.
- User adjustments: Users can adjust the device time at any time into
any direction.

I think we'll have to live with both and I'm not particularly worried
about them. My main objective is getting rid of the sleep drift.

Fixes #2590
Supersedes #22488, #22585, #23067, #23068

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…24903)

After Spans #23054, spans that run while the time origin is corrected
(e.g. after the device slept) get the drift added to their duration.
However, If the wall clock jumps backwards, the duration can even be
negative. Also, adding sleep time to spans is arguably unexpected and
unprecedented in comparison to OpenTelemetry.

This PR changes s `span.end()` without a explicit timestamp to compute
the end as start time + `performance.now()` time since the start, [like
OpenTelemetry
does](https://github.com/open-telemetry/opentelemetry-js/blob/672b1d216e8b2299d16d7e2dfd184da4bf448cb4/packages/sdk-trace/src/Span.ts#L319-L356).
Start times still use `timestampInSeconds()`, so real-time started spans
and spans from performance entries stay on the same timeline.

Tradeoff: when a correction happens while a span runs, its end is now
based on the old time origin. So children or errors recorded after the
correction can appear after the span ended. Spans with an explicit start
time keep using `timestampInSeconds()` for the end.

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Effect spans used Effect's own clock (a fixed origin plus a monotonic
clock) for their start, end and event times. #23054 makes Sentry correct
its clock for drift (e.g. after the device slept), so Effect spans could
end up shifted by the drift relative to the Sentry spans around them.
With this PR, an Effect span now starts on Sentry's clock, and its end
and event times are converted by their offset from the span's start.
This is the same per-span offset that OpenTelemetry's SDK uses. We also
do this for our spans now, see #24903 for details.

The PR keeps Effect's durations and any end time passed explicitly via
`span.end(time, exit)`. With `withTracerTiming(false)`, Effect passes
`0`, and we now use Sentry's clock instead of setting 1970 timestamps.

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

Ports the last three `cloudflare-integration-tests` suites that still
pinned `traceLifecycle: 'static'`.
`tracing/propagation/worker-do-rpc-overlapping` (#24447) and the two
`vite-autoinstrument/*-reexport-instrumented` suites (#23282) landed
while the earlier port PRs were open, so those PRs missed them.

The re-export suites check that `_INTERNAL_wrapUnlessInstrumented`
prevents a double wrap, so I made sure that the ported tests still catch
one. With the guard disabled, the Workflow suite receives two `step-one`
segment spans, and the WorkerEntrypoint request fails with `TypeError:
Cannot redefine property: __SENTRY_CONTEXT__`.

## Still pinned

- `suites/basic` stays as the static trace lifecycle guard, as named in
#24196.
- `suites/request-handler/subpath` stays pinned because of an SDK bug,
not a test problem. `wrapRequestHandler` from
`@sentry/cloudflare/request` still sends a `transaction` envelope. The
`/request` entry never sets an async context strategy, so `getClient()`
in `SentrySpan._onSpanEnded` returns `undefined` when the span ends, and
the span falls through to `_convertSpanToTransaction`. The scope
captured on the span does hold the streaming client. This needs a fix in
the SDK.

closes #24132

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

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
## Description

This brings back the `http.server` / `http.client` op and the
`auto.http.effect` origin on Effect HTTP spans with `effect@4.0.2` and
later. The tracer now also maps a span whose name is an HTTP method and
whose kind is `server` or `client`.

## Why

Effect-TS/effect#8873, released in `effect@4.0.2`, names HTTP spans
after the request method only (`GET` instead of `http.server GET`). The
tracer derived the op and origin from that name prefix, so the spans
lost both, and the `effect-4-node` E2E tests failed on `develop`.

## Span name decisions

The tracer keeps the name that Effect sets (`GET`). With the
`http.server` op, Sentry shows the segment as `GET /test-transaction`.
We could rename it back to `http.server GET`, but Effect chose the
OpenTelemetry naming on purpose.

## Known issues

- A user span named only after an HTTP method with a `server` or
`client` kind also gets the HTTP op.

## Sentry traces

Before (`develop`, `effect@4.0.2`, op `http`, origin `manual`):
https://sentry-sdks.sentry.io/explore/traces/trace/55137135a9a648f79a53d3a08f4d0546/
After (this PR, `effect@4.0.2`, op `http.server`, origin
`auto.http.effect`):
https://sentry-sdks.sentry.io/explore/traces/trace/11a9e7bfb1834bfbbdb9c4ddedd3dd76/

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Internal exception events skip event processors and `beforeSend` to
prevent recursion, so they must also omit attachments that those
callbacks would normally filter. Exclude attachments when building
internal event envelopes, including attachments added by send hooks,
while preserving ordinary event attachments and scope state.

Fixes [JS-2136](https://linear.app/getsentry/issue/JS-2136).

---------

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

The soft navigation web vitals tests hid the page right after the click.
Chrome only delivers the `soft-navigation` entry once the new route has
painted, so it can arrive after the page is hidden. web-vitals then
reports CLS for the pageload, and never finalizes the soft navigation's
metrics, so the test times out. This was flaky on `develop`, e.g. in
[this
run](https://github.com/getsentry/sentry-javascript/actions/runs/37587739193),
where `vue-3 (latest)` and `vue-3 (vue-router 5)` both timed out.

The tests now wait for the `soft-navigation` entry before calling
`hidePage`, using a new `waitForSoftNavigation` helper in `test-utils`.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The Replay integration adding web vital breadcrumbs used the metric
value as the timestamp for CLS and INP web vitals. This is incorrect
because that value is a score for CLS and a duration for INP, so both
events always landed just after page load. This was a pre-existing bug,
but it showed up during work on #23054. With this PR, CLS goes at the
last layout shift and INP at the interaction, like we already do with
spans in tracing. Both also get the time origin from when that happened,
so they stay correct after a clock drift correction. A CLS of 0 has no
layout shift, so it stays at the start of its navigation

---------

Co-authored-by: Claude <noreply@anthropic.com>
Follow-up to #23054, from [this review
comment](#23054 (comment)).
Besides `visibilitychange`, we now also check for clock drift on
`freeze`/`resume` (TIL) and `pagehide`/`pageshow`. This way the time
origin is corrected right at the emissions, not at the next regular
timestamp call.

`freeze` and `resume` only fire in Chromium. Other browsers never fire
them, so the listeners do nothing there.

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
SvelteKit 3 builds all environments in a single Vite build and runs the
adapter in a post `buildApp` hook. Our upload waited for a separate SSR
build in `closeBundle`, which Kit 3 never does, so nothing was uploaded.
We now also upload from a post `buildApp` hook, but only once an
environment has been built. Kit 2 builds only after all `buildApp` hooks
have run, so its `closeBundle` path still does the upload.

Source maps were also never deleted after upload, on Kit 2 or Kit 3. The
deletion check read `build.sourcemap` after our own plugin had already
set it.

The new `sveltekit-3-sourcemaps` e2e app builds against a mock Sentry
server. It asserts that the upload happens, that every debug ID has a
map, and that no maps are left in `build/`.

Fixes #25096

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Re-resolves three `@graphql-tools` lockfile entries to replace the
vulnerable
`@graphql-tools/utils` copy:

| Package | Before | After |
| --- | --- | --- |
| `@graphql-tools/schema` | 10.0.31 | 10.1.3 |
| `@graphql-tools/merge` | 9.1.7 | 9.2.6 |
| `@graphql-tools/utils` | 11.0.0 | 12.0.3 |

Fixes GHSA-7mx3-vvmw-hjmv (high), prototype pollution in `mergeDeep`:
https://github.com/getsentry/sentry-javascript/security/dependabot/2696

The first patched release is 12.0.1, so the fix has to cross a major. It
still
needs no `package.json` change: `@apollo/server` already declares
`@graphql-tools/schema@^10.0.0`, and schema 10.1.3 pulls `utils` into
12.x.
Lockfile-only diff, dev-only dependency path.

Verified with the affected suites, 52 passing:

yarn vitest run suites/tracing/apollo-graphql
suites/tracing/graphql-tracing-channel

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
(disclaimer, most of the additions are from `withSentry.test.ts` and
other tests)

Adds `withSentry` from `@sentry/nextjs/cloudflare` for the Worker entry
of a Next.js app on Cloudflare Workers, for example
`.open-next/worker.js` of OpenNext or the fetch handler of vinext. It is
`withSentry` of `@sentry/cloudflare` with the Next.js handling of the
server `init` added, so a Next.js app on Workers gets the spans it gets
on Node.js from one wrapper, without new options. This is the only new
public API.

Decisions:

- It installs the OpenTelemetry async context strategy at module load.
The AsyncLocalStorage strategy of `@sentry/cloudflare` loses the
OpenTelemetry context of the Next.js spans, so their parents and context
values break.
- The request spans of Next.js (`BaseServer.handleRequest`) are ignored,
so the request span of `withSentry` is the only `http.server` span. The
other Next.js spans become its children; it gets the route from their
`next.route` and its status from the response. When the middleware
answers the request or throws, the span is named `middleware GET`, like
the middleware segment on Node.js.
- From `compatibility_date` 2026-02-19, `process.cwd()` is `/bundle`
during a request. Next.js then misses its router server context and
extracts the incoming trace again. The propagator keeps the request span
as parent in that case, else each continued request has two segments.
- `sentry.server.config.ts` and `sentry.edge.config.ts` still run in the
Worker but create no client there. Their options do not apply, and a
debug log says so. On Workers they are optional: they only set the
`turbopack` tag and hand over the build release of `withSentryConfig`,
which only code that Next.js compiles can read. Without them, the
release comes from the `withSentry` options, `SENTRY_RELEASE` or
`CF_VERSION_METADATA`. Apps keep them for `next dev`, which runs on
Node.js and does not use the Worker entry. `instrumentation.ts` stays
required for `onRequestError`.
- The Next.js handling is added by a `Nextjs` integration. `withSentry`
of `@sentry/cloudflare` creates the client itself (once per isolate),
and the options callback only returns options. The `setup` of an
integration is the only place that gets this client before the request
span starts, without a new option in `@sentry/cloudflare`. It registers
the span hooks of the server `init`, the propagator, the tunnel route
sampling and the event processor that drops the control flow errors of
React and Next.js, so a Worker without `instrumentation.ts` drops them
too. The server `init` checks for this integration, so it does not add
the processor to the global scope again.
- `@sentry/cloudflare` becomes a dependency of `@sentry/nextjs`. Its
dependencies are already in the dependency tree of `@sentry/nextjs`. It
also aligns with other SDKs, such as `@sentry/sveltekit`

Known difference: on Workers, a release from the `withSentry` options,
`SENTRY_RELEASE` or `CF_VERSION_METADATA` wins over the build release.
On Node.js, the build release wins over the environment.

The `nextjs-16-cf-workers` e2e app now uses it, which un-skips its
server tests and adds tests for D1 spans, the OpenTelemetry context and
trace continuation.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
part of #24830
part of JS-3835

This folds `nextjs-16-bun` and `nextjs-16-cf-workers` into `nextjs-16`
and adds a Deno variant, so one suite runs on Node.js, Bun, Deno and
Cloudflare Workers (OpenNext). Bun and Cloudflare stay required. Deno
and Cloudflare with the latest Next.js are optional.

New tests on every runtime check logs, outgoing `baggage` and trace
continuation. Most removed lines are the two deleted apps.

## Why

The two copies of the app drifted apart, and Deno had no coverage. Now
all runtimes run the same tests, and each runtime difference is a
visible `getRuntime()` branch or skip.

## Known issues

- Bun and Deno need the request isolation and `fetch` integrations of
`@sentry/bun` and `@sentry/deno` in `sentry.server.config.ts`.
- Deno needs `--allow-sys` (the app runs `deno run -A`).
- No `pg` spans on Bun and Workers (no runtime module hook).

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…udflare` (#25000)

part of #19514
part of JS-1803

When a Vite build uses vinext and `@sentry/nextjs/cloudflare` resolves
from the Worker entry, the Vite plugin of `@sentry/cloudflare` now wraps
the entry with `withSentry` from `@sentry/nextjs/cloudflare`. Other
builds, and versions of `@sentry/nextjs` without that entry, keep
`@sentry/cloudflare`.

```diff
-import * as __SENTRY__ from '@sentry/cloudflare';
+import * as __SENTRY__ from '@sentry/nextjs/cloudflare';
 const __SENTRY_DEFAULT_EXPORT__ = { fetch() { ... } };
 export default __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);
```

## Why

With `withSentry` of `@sentry/cloudflare`, a vinext app on Workers sends
Cloudflare data but no Next.js spans. Now it gets the Next.js spans
without a config change.

## Traces

The same app and requests: vinext on Workers before and after this PR,
and `next start` on Node.js.

| Request | vinext before | vinext after | Next.js on Node.js |
| --- | --- | --- | --- |
| `GET /parameterized/42` | [`GET`, 1
span](https://sentry-sdks.sentry.io/explore/traces/trace/0f98d8ca6ef645e3ae5bb60c039eeb6d/)
| [`GET /parameterized/[id]`, 7
spans](https://sentry-sdks.sentry.io/explore/traces/trace/a26de83affd24b0c8fe7990e567ae8b6/)
| [`GET /parameterized/[id]`, 7
spans](https://sentry-sdks.sentry.io/explore/traces/trace/c24bdbb12b134e80a5417fe9d2a59c56/)
|
| `GET /api/hello` | [`GET`, 1
span](https://sentry-sdks.sentry.io/explore/traces/trace/df5b9f7976c5487daa7004cc9361eeeb/)
| [`GET /api/hello`, 4
spans](https://sentry-sdks.sentry.io/explore/traces/trace/75b4a831b48f4bb1adb13648f5c6419a/)
| [`GET /api/hello`, 4
spans](https://sentry-sdks.sentry.io/explore/traces/trace/ea8990c798144e2db75ee88e8bd6e634/)
|
| `GET /api/throw` (error) | [`GET`, 1
span](https://sentry-sdks.sentry.io/explore/traces/trace/b6389e0368e44b269e5e07ba9823c29a/)
| [`GET /api/throw`, 3
spans](https://sentry-sdks.sentry.io/explore/traces/trace/07caa661217e4f14bb38b182167d08c7/)
| [`GET /api/throw`, 3
spans](https://sentry-sdks.sentry.io/explore/traces/trace/c9a3a73e3c7a44d4b7ff6519c8760a7b/)
|

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ts/test-applications/nextjs-sourcemaps (#25170)

Bumps [next](https://github.com/vercel/next.js) from 16.2.11 to 16.3.8.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vercel/next.js/releases">next's
releases</a>.</em></p>
<blockquote>
<h2>v16.3.8</h2>
<p>This release contains security fixes for the following
advisories:</p>
<p>High:</p>
<ul>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-cjq9-62q9-8jv4">Server-Side
Request Forgery in Image Optimization</a></li>
</ul>
<p>Medium:</p>
<ul>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-f87g-xv8r-7p7x">Information
disclosure in Next.js App Router metadata image routes via dynamicParams
bypass</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-4jqv-mc3x-m676">Cache
poisoning of SSG and ISR pages in self-hosted Next.js
applications</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-mcj8-r9mp-w47p">Cache
poisoning in Next.js SSG/ISR rendering leads to cross-user content
substitution and persistent denial of service</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-3w37-wq28-93x7">Pending
<code>use cache</code> fill can leak Draft Mode content into regular
responses and persisted pages</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-h694-7cp9-m8p3">Cache
leak across root param values in nested 'use cache' functions</a></li>
</ul>
<p>Low:</p>
<ul>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-39w2-rjm5-chcv">Information
disclosure in the Next.js development server's Model Context Protocol
endpoint</a></li>
</ul>
<h2>v16.3.7</h2>
<blockquote>
<p>[!NOTE]
This release is backporting bug fixes. It does <strong>not</strong>
include all pending features/changes on canary.</p>
</blockquote>
<h3>Core Changes</h3>
<ul>
<li>turbo-tasks-backend: fix strongly consistent read hanging on a
canceled task (<a
href="https://redirect.github.com/vercel/next.js/issues/98931">#98931</a>)</li>
</ul>
<h3>Credits</h3>
<p>Huge thanks to <a
href="https://github.com/lukesandberg"><code>@​lukesandberg</code></a>
for helping!</p>
<h2>v16.3.6</h2>
<p>This release contains a security fix for <a
href="https://github.com/vercel/next.js/security/advisories/GHSA-vcvr-r3jv-pc5j">GHSA-vcvr-r3jv-pc5j:
Remote Code Execution in next/og ImageResponse</a></p>
<h2>v16.3.5</h2>
<p>The following bug fixes have been backported. It does not include all
pending features/changes on canary.</p>
<ul>
<li>next/image: Skip 0-byte entries when initializing disk LRU cache (<a
href="https://redirect.github.com/vercel/next.js/issues/98185">#98185</a>)</li>
<li>next/image: Reject empty images when reading/writing to the disk
cache (<a
href="https://redirect.github.com/vercel/next.js/issues/98186">#98186</a>)</li>
<li>Emit whole-app server NFTs when <code>output: 'standalone'</code> is
used with an adapter (<a
href="https://redirect.github.com/vercel/next.js/issues/98167">#98167</a>)</li>
<li>Add CSP nonce to script tags of loading and template files (<a
href="https://redirect.github.com/vercel/next.js/issues/98403">#98403</a>)</li>
<li>Fix <code>use cache</code> prerender signal retention (<a
href="https://redirect.github.com/vercel/next.js/issues/98448">#98448</a>)</li>
</ul>
<h2>v16.3.4</h2>
<p>Follow-up release to <a
href="https://github.com/vercel/next.js/releases/tag/v16.3.3">v16.3.3</a>
re-enabling AVIF Image Optimization (<a
href="https://redirect.github.com/vercel/next.js/pull/97949">#97949</a>).</p>
<p>The following bug fixes have been backported. It does
<strong>not</strong> include all pending features/changes on canary.</p>
<ul>
<li>testmode: Fix infinite recursion in testmode passthrough fetch (<a
href="https://redirect.github.com/vercel/next.js/issues/97691">#97691</a>)</li>
<li>Fix build error when aliasing typescript to
<code>@​typescript/typescript6</code> (<a
href="https://redirect.github.com/vercel/next.js/issues/97997">#97997</a>)</li>
<li>Fix unset crossOrigin in Turbopack manifests (<a
href="https://redirect.github.com/vercel/next.js/issues/97930">#97930</a>)</li>
</ul>
<h3>Credits</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vercel/next.js/commit/b0fad0d45eb4c4430fda5eeeb442e8a5af08a5f6"><code>b0fad0d</code></a>
v16.3.8</li>
<li><a
href="https://github.com/vercel/next.js/commit/719e4c67d6e92df60246f95e1d96e2dd60789a52"><code>719e4c6</code></a>
[lts-active] Scope response cache keys to their source route (<a
href="https://redirect.github.com/vercel/next.js/issues/218">#218</a>)</li>
<li><a
href="https://github.com/vercel/next.js/commit/e92db4536a7f34ae2dbda583cfa1b4e0d06d1865"><code>e92db45</code></a>
[lts-active] Fix metadata propagation for deduplicated nested caches (<a
href="https://redirect.github.com/vercel/next.js/issues/223">#223</a>)</li>
<li><a
href="https://github.com/vercel/next.js/commit/40c2ba904289a65ed2fd4633c5dfb1bdc29b52de"><code>40c2ba9</code></a>
[lts-active] Match Next data paths case-sensitively (<a
href="https://redirect.github.com/vercel/next.js/issues/196">#196</a>)</li>
<li><a
href="https://github.com/vercel/next.js/commit/2d9f50a409312696145b82b3157aadb6b1fef476"><code>2d9f50a</code></a>
[lts-active] Fix MCP middleware DNS rebinding (<a
href="https://redirect.github.com/vercel/next.js/issues/213">#213</a>)</li>
<li><a
href="https://github.com/vercel/next.js/commit/bd9214f9a32854a011bf5fe58e481dffe1bbf598"><code>bd9214f</code></a>
[lts-active] Fix draft mode leaks through cross-request <code>'use
cache'</code> dedupli...</li>
<li><a
href="https://github.com/vercel/next.js/commit/8db4a627c91e718514406ff5644ea4985dcaaae0"><code>8db4a62</code></a>
[lts-active][webpack] Ensure <code>dynamicParams</code> is respected in
`opengraph-image...</li>
<li><a
href="https://github.com/vercel/next.js/commit/e002ad68bd676bb0ed0c87bb22e3590304763e0b"><code>e002ad6</code></a>
[lts-active] fix(next/image): Pin DNS resolution when fetching external
image...</li>
<li><a
href="https://github.com/vercel/next.js/commit/4c20699e29178d444994cf5a31b8a617ca3a2c80"><code>4c20699</code></a>
v16.3.7</li>
<li><a
href="https://github.com/vercel/next.js/commit/2521aec5815e7de2121db253d12dae9f13e25361"><code>2521aec</code></a>
[backport] turbo-tasks-backend: fix strongly consistent read hanging on
a can...</li>
<li>Additional commits viewable in <a
href="https://github.com/vercel/next.js/compare/v16.2.11...v16.3.8">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=next&package-manager=npm_and_yarn&previous-version=16.2.11&new-version=16.3.8)](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)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/getsentry/sentry-javascript/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Port AMQP tests to span streaming.

Part of #24137

---------

Co-authored-by: GPT-6 <codex@openai.com>
nicohrubec and others added 10 commits October 8, 2026 14:31
Port Tedious tests to span streaming.

Part of #24137

---------

Co-authored-by: GPT-6 <codex@openai.com>
Port MySQL and MySQL2 diagnostics-channel tests to default span
streaming. Keep the original MySQL2 suite static for transaction
coverage.

Part of #24137

---------

Co-authored-by: GPT-6 <codex@openai.com>
Adds `piDurableIntegration` for
[`@earendil-works/pi-durable`](https://github.com/earendil-works/pi/tree/main/packages/durable),
Earendil's new durable agent harness. It is on by default in Node, Bun
and Deno, and in a Worker built with `@sentry/cloudflare/vite`, which
covers pi-durable in a Durable Object through the Agents SDK
`PiHarness`. Each run becomes its own `invoke_agent` trace with `chat`
and `execute_tool` children, and the first run of a subagent
conversation nests under the tool call that created it.

pi-durable has no telemetry hooks (`pi-telemetry` exists, but no pi
package emits spans through it yet), so the integration hooks
`Harness.open()` and wraps the `models` and `registry` it receives. The
wrapped options keep the caller's options as prototype, because
pi-durable reads `settings`, `env` and `conversationCreated` at every
use.

Decisions worth a look:

- **Runs are tracked per conversation.** pi-durable hands run control to
a new `pi.generation` task after every tool round, so no single task
spans a run. The run span ends when the commit that removes
`pi.live.run` goes through, or when the Harness closes with the run in
flight.
- **Each run starts a new trace in clean scopes.** The scheduler runs
task phases in whatever async context last woke it, often an unrelated
request. Forking that context attached runs to the wrong request and the
wrong conversation. Only the client of that context is kept, because
`@sentry/cloudflare` binds the client to the scope of each request, not
to the default scope.
- **`gen_ai.conversation.id` is `<harness id>:<conversation id>`.**
pi-durable numbers conversations per storage from 1, so the bare id
would merge every root conversation into one. The cost is a new id after
a restart (on Cloudflare, after every restart of the Durable Object),
until pi-durable has a stable storage id.
- **Tool spans record the result the model receives**, read from the
committed result entry. That covers output streamed through
`api.output()` (all of `bash`) and results an `afterTool` hook redacted.
- **Errors:** failures pi-durable only passes to `onReport` (throwing
hooks or sections) and task phases that throw are captured. Throws of
the built-in coding tools are not, because `bash` throws for every
non-zero exit, a normal result for a coding agent. The built-in tools
are recognized by their factories (`createBashTool()` and friends), so
an app that registers them in an extension of its own gets the same
treatment. The span keeps its error status.
- **The provider SDK integrations are skipped process-wide** from the
first run on, as the Flue and LangChain integrations do: pi-ai sends its
requests through the `openai`, `@anthropic-ai/sdk` and `@google/genai`
clients, or through the Workers AI binding with `createAI()` of
`agents/models/pi-ai`, and those integrations cannot tell pi-ai's calls
from the app's own. Bedrock requests go through the AWS SDK, which
`awsIntegration` still reports twice; that skip is a follow-up.

Messages, token usage and finish reasons go through the pi-ai mapper
from the Flue fix, and the system prompt and tools are replayed from
pi-durable's positional system messages.

Not covered yet: spans for tool calls pi-durable answers without running
`execute()`, spans for custom tasks, agent names (pi-durable has none),
a link between a run and the request that submitted it, a marker for
compaction requests, and an error event for a failed model request (the
`chat` span carries the status).

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Andrei <168741329+andreiborza@users.noreply.github.com>
Adds an E2E app for the pi-durable instrumentation. It covers what the
node integration test cannot: the packed SDK loaded with `--import`,
real model requests through OpenRouter, SQLite storage, a subagent, and
a run that resumes after the server crashes during a tool call. A small
supervisor restarts the server for that case, as a process manager
would.

pi-ai sends `anthropic/claude-haiku-4.5` through `@anthropic-ai/sdk`, so
the first test also checks that each model request is reported once and
that the provider's HTTP call nests inside its `chat` span.

The app is optional with a `latest` variant, because
`E2E_OPENROUTER_API_KEY` is only available in the optional E2E job.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
The Agents SDK `PiHarness`
([changelog](https://developers.cloudflare.com/changelog/post/2026-10-02-pi-harness/))
keeps the state of pi-durable in the SQLite database of the Durable
Object, in tables with the `pi_` prefix of its session store. Each
statement became a `db.query` span: one run with one tool call had 189
of them next to its 7 agent spans, and the request that submitted the
prompt had 120 more. These statements are framework bookkeeping, like
the ones on the `cf_` tables of `agents`, so they are now skipped the
same way, and `durableObjectSqlSpanAllowlist: [/^pi_/]` brings them
back.

The cost is the same as for `cf_`: a user table whose name starts with
`pi_` also loses its spans until it is on the allowlist. Names such as
`api_keys` or `pipelines` are not affected.

Before: [196
spans](https://sentry-sdks.sentry.io/explore/traces/trace/7da432828f034a709be522a7de5bd4e2/),
after: [7
spans](https://sentry-sdks.sentry.io/explore/traces/trace/0a8c909bd53a4d61b78f98af21fc1ebb/)
for the same prompt.

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

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Cloudflare now hosts pi-durable in Durable Objects through the Agents
SDK `PiHarness`
([changelog](https://developers.cloudflare.com/changelog/post/2026-10-02-pi-harness/)).
This app runs pi-durable that way, with `@sentry/cloudflare/vite` as the
only Sentry setup. It checks that a prompt becomes an `invoke_agent`
trace with `chat`, `execute_tool` and provider `http.client` spans, that
a throwing tool is reported on its span, and that a run resumes in a new
trace after the Durable Object resets during a tool call. The reset uses
`ctx.abort()`, which drops the object like an eviction; the next request
starts it again, and `PiHarness` resumes pi from its SQLite state.

Like `node-pi-durable` and `cloudflare-think`, it calls a real model
through OpenRouter, so it is optional. The changelog example uses
Workers AI (`createAI({ binding: env.AI })`), but the AI binding needs a
Cloudflare account even in local dev, so that path has a unit test in
#24993 instead.

This app found a bug that #24993 now fixes: `@sentry/cloudflare`
initializes the SDK inside each request, so the client is on the scope
of that request only. The task phases ran on a copy of the default
scope, had no client, and dropped every pi-durable span and error.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ate spans (#25044)

## What

Mastra classifier evaluations (Jev calls through Mastra's `Classifier`,
its processors and scorers) now show up as `gen_ai.evaluate` spans with
model, provider and token usage. When gen_ai recording is on, they also
record the evaluated state, questions and answers.

## Why

These calls skip the AI SDK hook, and our Mastra exporter dropped their
spans, so they were invisible.

Closes: #25031

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
## What

Adds a node-mastra e2e test that runs a real Jev evaluation through a
Mastra `Classifier` (via OpenRouter) and checks the `gen_ai.evaluate`
span.

## Why

Covers the classifier instrumentation from #25044 against the real
provider, not only a mock model.
Browser page loads in Remix 3 started a new trace. The server middleware
now adds `sentry-trace` and `baggage` entries to the `Server-Timing`
header of HTML responses, ahead of the route entry, the same channel the
Remix 2 SDK and Nitro use. The browser SDK already reads both off the
navigation timing entry for page loads, so no client change is needed.

A response a shared cache may store (`public`, `s-maxage`, or a positive
`max-age` without `private`/`no-store`) carries the route entry only: a
cached document would otherwise hand one request's trace to every later
page load, the ISR problem the Next.js SDK works around on the client.

The e2e test asserts that the page load span shares the server span's
trace id and has it as parent.

Fixes #25137

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
@JPeer264 JPeer264 self-assigned this Oct 8, 2026
@JPeer264
JPeer264 requested review from a team as code owners October 8, 2026 13:32
@JPeer264
JPeer264 requested review from andreiborza, msonnb, mydea, nicohrubec and s1gr1d and removed request for a team October 8, 2026 13:32
@github-actions

github-actions Bot commented Oct 8, 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.8 kB +0.68% +200 B 🔺
@sentry/browser - with treeshaking flags 27.92 kB +0.62% +170 B 🔺
@sentry/browser - with treeshaking flags tracing without tracing 27.84 kB +0.68% +188 B 🔺
@sentry/browser (incl. Tracing) 51.85 kB +0.66% +335 B 🔺
@sentry/browser (incl. Tracing + Span Streaming) 51.87 kB +0.68% +350 B 🔺
@sentry/browser (incl. Tracing, Profiling) 54.8 kB +0.56% +302 B 🔺
@sentry/browser (incl. Tracing, Replay) 91.58 kB +0.4% +356 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 80.45 kB +0.33% +264 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas) 96.29 kB +0.38% +363 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback) 109.27 kB +0.36% +382 B 🔺
@sentry/browser (incl. Feedback) 47.32 kB +0.43% +201 B 🔺
@sentry/browser (incl. sendFeedback) 34.84 kB +0.55% +188 B 🔺
@sentry/browser (incl. FeedbackAsync) 39.95 kB +0.5% +197 B 🔺
@sentry/browser (incl. Metrics) 30.82 kB +0.71% +217 B 🔺
@sentry/browser (incl. Logs) 31.11 kB +0.72% +221 B 🔺
@sentry/browser (incl. Metrics & Logs) 31.75 kB +0.63% +196 B 🔺
@sentry/react 31.63 kB +0.64% +201 B 🔺
@sentry/react (incl. Tracing) 54.17 kB +0.63% +335 B 🔺
@sentry/vue 37.84 kB +0.77% +289 B 🔺
@sentry/vue (incl. Tracing) 54.78 kB +0.71% +381 B 🔺
@sentry/svelte 29.83 kB +0.69% +203 B 🔺
@sentry/remix (Remix 3 client bundle) 56.83 kB +0.51% +286 B 🔺
CDN Bundle 31.53 kB +0.65% +202 B 🔺
CDN Bundle (incl. Tracing) 52.34 kB +0.54% +277 B 🔺
CDN Bundle (incl. Logs, Metrics) 33.72 kB +0.48% +159 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) 54.3 kB +0.51% +272 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) 74.65 kB +0.36% +267 B 🔺
CDN Bundle (incl. Tracing, Replay) 90.01 kB +0.31% +274 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 91.96 kB +0.3% +269 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 96.17 kB +0.29% +275 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 98.15 kB +0.29% +280 B 🔺
CDN Bundle - uncompressed 92.92 kB +0.5% +460 B 🔺
CDN Bundle (incl. Tracing) - uncompressed 155.46 kB +0.45% +689 B 🔺
CDN Bundle (incl. Logs, Metrics) - uncompressed 99.46 kB +0.43% +419 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 161.41 kB +0.43% +689 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 229.5 kB +0.23% +518 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed 275.63 kB +0.27% +737 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 281.57 kB +0.27% +737 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 289.33 kB +0.26% +737 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 295.26 kB +0.26% +737 B 🔺
@sentry/nextjs (client) 56.53 kB +0.61% +342 B 🔺
@sentry/sveltekit (client) 52.23 kB +0.64% +327 B 🔺
@sentry/core/server 40.86 kB +0.52% +209 B 🔺
@sentry/core/browser 13.71 kB +1.48% +199 B 🔺
@sentry/node 150.85 kB +3.64% +5.29 kB 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 83.56 kB +0.41% +339 B 🔺
@sentry/node - without tracing 93.98 kB +0.57% +526 B 🔺
@sentry/node - without channel injection 129 kB +4.28% +5.28 kB 🔺
@sentry/aws-serverless 102.14 kB +0.45% +454 B 🔺
@sentry/cloudflare (withSentry) - minified 209.81 kB +0.38% +780 B 🔺
@sentry/cloudflare (withSentry) 520.23 kB +0.47% +2.43 kB 🔺
@sentry/nextjs/cloudflare (withSentry) - minified 227.48 kB added added

View base workflow run

* them from the call. Mastra ends its span before `evaluate()` returns the answers, so the exporter
* leaves the Sentry span open and the integration ends it once the call settles.
*/
export interface ClassifierEvaluationCall {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The module-level singleton startingCall creates a race condition. Concurrent Classifier.evaluate() calls can overwrite this variable, leading to mismatched or lost trace data.
Severity: HIGH

Suggested Fix

Replace the global startingCall singleton with a context-aware mechanism like AsyncLocalStorage to maintain state per asynchronous execution context. Alternatively, correlate calls using their unique message object instead of relying on a shared global variable to avoid race conditions.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: packages/server-utils/src/ai/mastra/classifier-evaluation.ts#L10

Potential issue: A race condition exists due to the module-level singleton
`startingCall` in `classifier-evaluation.ts`. In a concurrent environment, if two
`Classifier.evaluate()` calls start close together, the second call's `channel.start`
handler can overwrite the `startingCall` variable before the first call's `span_started`
handler runs. This causes `takeStartingClassifierEvaluation()` to return the wrong call
object for the first evaluation and potentially `undefined` for the second. The result
is corrupted trace data, where spans are attributed to the wrong evaluation or lost
completely. This is likely to occur in a production server handling multiple concurrent
requests.

Also affects:

  • packages/server-utils/src/integrations/mastra-classifier.ts:29~31
  • packages/server-utils/src/integrations/mastra-classifier.ts:58~60

Did we get this right? 👍 / 👎 to inform future reviews.

@JPeer264
JPeer264 enabled auto-merge October 8, 2026 14:12
@JPeer264
JPeer264 merged commit 13743e9 into master Oct 8, 2026
350 of 353 checks passed
@JPeer264
JPeer264 deleted the prepare-release/11.6.0 branch October 8, 2026 14:20
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.

8 participants