DISCLAIMER: THIS MIGRATION GUIDE IS WORK IN PROGRESS
Version 9 of the Sentry SDK concerns API cleanup and compatibility updates. This update contains behavioral changes that will not be caught by TypeScript or linters, so we recommend carefully reading the section on Behavioral Changes.
Before updating to version 9.x
of the SDK, we recommend upgrading to the latest version of 8.x
.
You can then go through the Deprecations in 8.x and remove and migrate usages of deprecated APIs in your code before upgrading to 9.x
.
Version 9 of the JavaScript SDK is compatible with Sentry self-hosted versions 24.4.2 or higher (unchanged from last major). Lower versions may continue to work, but may not support all features.
Version 9 of the Sentry SDK has new compatibility ranges for runtimes and frameworks. We periodically update the compatibility ranges in major versions to increase the reliability and quality of APIs and instrumentation data.
ECMAScript Version: All the JavaScript code in the Sentry SDK packages may now contain ECMAScript 2020 features.
This includes features like Nullish Coalescing (??
), Optional Chaining (?.
), String.matchAll()
, Logical Assignment Operators (&&=
, ||=
, ??=
), and Promise.allSettled()
.
If you observe failures due to syntax or features listed above, it may indicate that your current runtime does not support ES2020. If your runtime does not support ES2020, we recommend transpiling the SDK using Babel or similar tooling.
Node.js: The minimum supported Node.js version is 18.0.0, except for ESM-only SDKs (nuxt, solidstart, astro) which require Node 18.19.1 or up. We no longer test against Node 14 and Node 16 and cannot guarantee that the SDK will work as expected on these versions.
Browsers: Due to SDK code now including ES2020 features, the minimum supported browser list now looks as follows:
- Chrome 80
- Edge 80
- Safari 14, iOS Safari 14.4
- Firefox 74
- Opera 67
- Samsung Internet 13.0
If you need to support older browsers, we recommend transpiling your code using Babel or similar tooling.
Deno: The minimum supported Deno version is now 2.0.0.
Support for the following frameworks and library versions are dropped:
- Remix: Version
1.x
- TanStack Router: Version
1.63.0
and lower (relevant when usingtanstackRouterBrowserTracingIntegration
) - SvelteKit: Version
1.x
- Ember.js: Version
3.x
and lower (minimum supported version is4.x
) - Prisma: Version
5.x
In preparation for the OpenTelemetry SDK v2, which will raise the minimum required TypeScript version, the minimum required TypeScript version is increased to version 5.0.4
(TBD open-telemetry/opentelemetry-js#5145).
Additionally, like the OpenTelemetry SDK, the Sentry JavaScript SDK will follow DefinitelyType's version support policy which has a support time frame of 2 years for any released version of TypeScript.
Older Typescript versions may still work, but we will not test them anymore and no more guarantees apply.
-
If you use the optional
captureConsoleIntegration
and setattachStackTrace: true
in yourSentry.init
call, console messages will no longer be marked as unhandled (i.e.handled: false
) but as handled (i.e.handled: true
). If you want to keep sending them as unhandled, configure thehandled
option when adding the integration:Sentry.init({ integrations: [Sentry.captureConsoleIntegration({ handled: false })], attachStackTrace: true, });
-
Dropping spans in the
beforeSendSpan
hook is no longer possible. -
The
beforeSendSpan
hook now receives the root span as well as the child spans. -
In previous versions, we determined if tracing is enabled (for Tracing Without Performance) by checking if either
tracesSampleRate
ortraceSampler
are defined at all, inSentry.init()
. This means that e.g. the following config would lead to tracing without performance (=tracing being enabled, even if no spans would be started):Sentry.init({ tracesSampleRate: undefined, });
In v9, an
undefined
value will be treated the same as if the value is not defined at all. You'll need to settracesSampleRate: 0
if you want to enable tracing without performance. -
The
getCurrentHub().getIntegration(IntegrationClass)
method will always returnnull
in v9. This has already stopped working mostly in v8, because we stopped exposing integration classes. In v9, the fallback behavior has been removed. Note that this does not change the type signature and is thus not technically breaking, but still worth pointing out. -
The
startSpan
behavior was slightly changed if you pass a customscope
to the span start options: While in v8, the passed scope was set active directly on the passed scope, in v9, the scope is cloned. This behavior change does not apply to@sentry/node
where the scope was already cloned. This change was made to ensure that the span only remains active within the callback and to align behavior between@sentry/node
and all other SDKs. As a result of the change, your span hierarchy should be more accurate. However, be aware that modifying the scope (e.g. set tags) within thestartSpan
callback behaves a bit differently now.startSpan({ name: 'example', scope: customScope }, () => { getCurrentScope().setTag('tag-a', 'a'); // this tag will only remain within the callback // set the tag directly on customScope in addition, if you want to to persist the tag outside of the callback customScope.setTag('tag-a', 'a'); });
-
When
skipOpenTelemetrySetup: true
is configured,httpIntegration({ spans: false })
will be configured by default.This means that you no longer have to specify this yourself in this scenario. With this change, no spans are emitted once
skipOpenTelemetrySetup: true
is configured, without any further configuration being needed. -
The
requestDataIntegration
will no longer automatically set the user fromrequest.user
. This is an express-specific, undocumented behavior, and also conflicts with our privacy-by-default strategy. Starting in v9, you'll need to manually callSentry.setUser()
e.g. in a middleware to set the user on Sentry events. -
The
tracesSampler
hook will no longer be called for every span. Instead, it will only be called for "root spans". Root spans are spans that have no local parent span. Root spans may however have incoming trace data from a different service, for example when using distributed tracing. -
The
childProcessIntegration
's (previouslyprocessThreadBreadcrumbIntegration
)name
value has been changed from"ProcessAndThreadBreadcrumbs"
to"ChildProcess"
. This is relevant if you were filtering integrations by name. -
The Prisma integration no longer supports Prisma v5 and supports Prisma v6 by default. As per Prisma v6, the
previewFeatures = ["tracing"]
client generator option in your Prisma Schema is no longer required to use tracing with the Prisma integration.For performance instrumentation using other/older Prisma versions:
-
Install the
@prisma/instrumentation
package with the desired version. -
Pass a
new PrismaInstrumentation()
instance as exported from@prisma/instrumentation
to theprismaInstrumentation
option of this integration:import { PrismaInstrumentation } from '@prisma/instrumentation'; Sentry.init({ integrations: [ prismaIntegration({ // Override the default instrumentation that Sentry uses prismaInstrumentation: new PrismaInstrumentation(), }), ], });
The passed instrumentation instance will override the default instrumentation instance the integration would use, while the
prismaIntegration
will still ensure data compatibility for the various Prisma versions. -
Depending on your Prisma version (prior to Prisma version 6), add
previewFeatures = ["tracing"]
to the client generator block of your Prisma schema:generator client { provider = "prisma-client-js" previewFeatures = ["tracing"] }
-
- The SDK no longer instructs the Sentry backend to automatically infer IP addresses by default. This means that places where you previously saw IP addresses in Sentry may now be grouped to anonymous users. Set the
sendDefaultPii
option inSentry.init()
to true to instruct the Sentry backend to infer IP addresses. - The
captureUserFeedback
method has been removed. Use thecaptureFeedback
method instead and update thecomments
field tomessage
.
-
The Sentry Next.js SDK will no longer use the Next.js Build ID as fallback identifier for releases. The SDK will continue to attempt to read CI-provider-specific environment variables and the current git SHA to automatically determine a release name. If you examine that you no longer see releases created in Sentry, it is recommended to manually provide a release name to
withSentryConfig
via therelease.name
option.This behavior was changed because the Next.js Build ID is non-deterministic and the release name is injected into client bundles, causing build artifacts to be non-deterministic. This caused issues for some users. Additionally, because it is uncertain whether it will be possible to rely on a Build ID when Turbopack becomes stable, we decided to pull the plug now instead of introducing confusing behavior in the future.
-
Source maps are now automatically enabled for both client and server builds unless explicitly disabled via
sourcemaps.disable
. Client builds usehidden-source-map
while server builds usesource-map
as their webpackdevtool
setting unless any other value thanfalse
orundefined
has been assigned already. -
By default, source maps will now be automatically deleted after being uploaded to Sentry for client-side builds. You can opt out of this behavior by explicitly setting
sourcemaps.deleteSourcemapsAfterUpload
tofalse
in your Sentry config. -
The
sentry
property on the Next.js config object has officially been discontinued. Pass options towithSentryConfig
directly.
-
Updated source map generation to respect the user-provided value of your build config, such as
vite.build.sourcemap
:- Explicitly disabled (false): Emit warning, no source map upload.
- Explicitly enabled (true, 'hidden', 'inline'): No changes, source maps are uploaded and not automatically deleted.
- Unset: Enable 'hidden', delete
.map
files after uploading them to Sentry.
To customize which files are deleted after upload, define the
filesToDeleteAfterUpload
array with globs.
The componentStack
field in the ErrorBoundary
component is now typed as string
instead of string | null | undefined
for the onError
and onReset
lifecycle methods. This more closely matches the actual behavior of React, which always returns a string
whenever a component stack is available.
In the onUnmount
lifecycle method, the componentStack
field is now typed as string | null
. The componentStack
is null
when no error has been thrown at time of unmount.
TODO
As part of an architectural cleanup, we deprecated the following packages:
@sentry/utils
@sentry/types
All of these packages exports and APIs have been moved into the @sentry/core
package.
The @sentry/utils
package will no longer be published.
The @sentry/types
package will continue to be published but it is deprecated and we don't plan on extending its API.
You may experience slight compatibility issues in the future by using it.
We decided to keep this package around to temporarily lessen the upgrade burden.
It will be removed in a future major version.
- The
debugIntegration
has been removed. To log outgoing events, use Hook Options (beforeSend
,beforeSendTransaction
, ...). - The
sessionTimingIntegration
has been removed. To capture session durations alongside events, use Context (Sentry.setContext()
). - The
addOpenTelemetryInstrumentation
method has been removed. Use theopenTelemetryInstrumentations
option inSentry.init()
or your custom Sentry Client instead.
import * as Sentry from '@sentry/node';
// before
Sentry.addOpenTelemetryInstrumentation(new GenericPoolInstrumentation());
// after
Sentry.init({
openTelemetryInstrumentations: [new GenericPoolInstrumentation()],
});
- The
DEFAULT_USER_INCLUDES
constant has been removed. - The
getCurrentHub()
,Hub
andgetCurrentHubShim()
APIs have been removed. They were on compatibility life support since the release of v8 and have now been fully removed from the SDK.
- The
captureUserFeedback
method has been removed. Use thecaptureFeedback
method instead and update thecomments
field tomessage
.
- The
getNumberOfUrlSegments
method has been removed. There is no replacement. - The
validSeverityLevels
export has been removed. There is no replacement. - The
makeFifoCache
method has been removed. There is no replacement. - The
arrayify
export has been removed. There is no replacement. - The
BAGGAGE_HEADER_NAME
export has been removed. Use the"baggage"
string constant directly instead. - The
flatten
export has been removed. There is no replacement. - The
urlEncode
method has been removed. There is no replacement. - The
getDomElement
method has been removed. There is no replacement. - The
memoBuilder
method has been removed. There is no replacement. - The
extractRequestData
method has been removed. Manually extract relevant data off request instead. - The
addRequestDataToEvent
method has been removed. UsehttpRequestToRequestData
instead and put the resulting object directly onevent.request
. - The
extractPathForTransaction
method has been removed. There is no replacement. - The
addNormalizedRequestDataToEvent
method has been removed. UsehttpRequestToRequestData
instead and put the resulting object directly onevent.request
. - A
sampleRand
field onPropagationContext
is now required. This is relevant if you usedscope.setPropagationContext(...)
-
The
sentrySolidStartVite
plugin is no longer exported. Instead, wrap the SolidStart config withwithSentry
and provide Sentry options as the second parameter.// app.config.ts import { defineConfig } from '@solidjs/start/config'; import { withSentry } from '@sentry/solidstart'; export default defineConfig(withSentry( { /* SolidStart config */ }, { /* Sentry build-time config (like project and org) */ }) );
The following changes are unlikely to affect users of the SDK. They are listed here only for completion sake, and to alert users that may be relying on internal behavior.
client._prepareEvent()
now requires a currentScope & isolationScope to be passed as last arugmentsclient.recordDroppedEvent()
no longer accepts anevent
as third argument. The event was no longer used for some time, instead you can (optionally) pass a count of dropped events as third argument.
- Removed
WithSentry
decorator. Use theSentryExceptionCaptured
decorator instead. - Removed
SentryService
.- If you are using
@sentry/nestjs
you can safely remove any references to theSentryService
. - If you are using another package migrate to
@sentry/nestjs
and remove theSentryService
afterward.
- If you are using
- Removed
SentryTracingInterceptor
.- If you are using
@sentry/nestjs
you can safely remove any references to theSentryTracingInterceptor
. - If you are using another package migrate to
@sentry/nestjs
and remove theSentryTracingInterceptor
afterward.
- If you are using
- Removed
SentryGlobalGenericFilter
.- Use the
SentryGlobalFilter
instead. - The
SentryGlobalFilter
is a drop-in replacement.
- Use the
- Removed
SentryGlobalGraphQLFilter
.- Use the
SentryGlobalFilter
instead. - The
SentryGlobalFilter
is a drop-in replacement.
- Use the
- The
wrapUseRoutes
method has been removed. Use thewrapUseRoutesV6
orwrapUseRoutesV7
methods instead depending on what version of react router you are using. - The
wrapCreateBrowserRouter
method has been removed. Use thewrapCreateBrowserRouterV6
orwrapCreateBrowserRouterV7
methods depending on what version of react router you are using.
-
The options
tracingOptions
,trackComponents
,timeout
,hooks
have been removed everywhere except in thetracingOptions
option ofvueIntegration()
.These options should now be set as follows:
import * as Sentry from '@sentry/vue'; Sentry.init({ integrations: [ Sentry.vueIntegration({ tracingOptions: { trackComponents: true, timeout: 1000, hooks: ['mount', 'update', 'unmount'], }, }), ], });
-
The option
logErrors
in thevueIntegration
has been removed. The Sentry Vue error handler will propagate the error to a user-defined error handler or just re-throw the error (which will log the error without modifying).
- Removed
getPropagationContextFromSpan
. This function was primarily internally used. It's functionality was misleading and should not be used.
- The
fetchProxyScriptNonce
option insentryHandle()
was removed due to security concerns. If you previously specified this option for your CSP policy, specify a script hash in your CSP config or disable the injection of the script entirely.
Previously the CJS versions of the SDK code (wrongfully) contained compatibility statements for default exports in ESM:
Object.defineProperty(exports, '__esModule', { value: true });
The SDK no longer contains these statements. Let us know if this is causing issues in your setup by opening an issue on GitHub.
The minimum supported Deno version is now 2.0.0.
@sentry/deno
is no longer published ondeno.land
so you'll need to import from npm:
import * as Sentry from 'npm:@sentry/deno';
Sentry.init({
dsn: '__DSN__',
// ...
});
In v8, types have been exported from @sentry/types
, while implementations have been exported from other classes.
This led to some duplication, where we had to keep an interface in @sentry/types
, while the implementation mirroring that interface was kept e.g. in @sentry/core
.
Since v9, the types have been merged into @sentry/core
, which removed some of this duplication. This means that certain things that used to be a separate interface, will not expect an actual instance of the class/concrete implementation.
This should not affect most users unless you relied on passing things with a similar shape to internal methods. The following types are affected:
Scope
now always expects theScope
class- The
TransactionNamingScheme
type has been removed. There is no replacement. - The
Request
type has been removed. UseRequestEventData
type instead. - The
IntegrationClass
type is no longer exported - it was not used anymore. Instead, useIntegration
orIntegrationFn
. - The
samplingContext.request
attribute in thetracesSampler
has been removed. UsesamplingContext.normalizedRequest
instead. Note that the type ofnormalizedRequest
differs fromrequest
. - The
samplingContext.transactionContext
object in thetracesSampler
has been removed. All object attributes are available in the top-level ofsamplingContext
. Client
now always expects theBaseClient
class - there is no more abstractClient
that can be implemented! AnyClient
class has to extend fromBaseClient
.ReportDialogOptions
now extendsRecord<string, unknown>
instead ofRecord<string, any>
- this should not affect most users.- The
RequestDataIntegrationOptions
type has been removed. There is no replacement.
Version support timelines are stressful for anybody using the SDK, so we won't be defining one. Instead, we will be applying bug fixes and features to older versions as long as there is demand for them.
We also hold ourselves to high standards security-wise, meaning that if any vulnerabilities are found, we will in almost all cases backport them.
Note, that we will decide on a case-per-case basis, what gets backported or not. If you need a fix or feature in a previous version of the SDK, feel free to reach out via a GitHub issue.
The following outlines deprecations that were introduced in version 8 of the SDK.
-
Returning
null
frombeforeSendSpan
span is deprecated.Returning
null
frombeforeSendSpan
will now result in a warning being logged. In v9, dropping spans is not possible anymore within this hook. -
Passing
undefined
totracesSampleRate
/tracesSampler
/enableTracing
will be handled differently in v9
In v8, explicitly setting tracesSampleRate
(even if it is set to undefined
) resulted in tracing being enabled, although no spans were generated.
Sentry.init({
tracesSampleRate: undefined,
});
In v9, we will streamline this behavior so that passing undefined
will result in tracing being disabled, the same as not passing the option at all.
If you are relying on undefined
being passed in and having tracing enabled because of this, you should update your config to set e.g. tracesSampleRate: 0
instead, which will also enable tracing in v9.
The enableTracing
option was removed. In v9, to emulate enableTracing: true
, set tracesSampleRate: 1
. To emulate enableTracing: false
, remove the tracesSampleRate
and tracesSampler
options (if configured).
- The
autoSessionTracking
option is deprecated.
To enable session tracking, it is recommended to unset autoSessionTracking
and ensure that either, in browser environments the browserSessionIntegration
is added, or in server environments the httpIntegration
is added.
To disable session tracking, it is recommended unset autoSessionTracking
and to remove the browserSessionIntegration
in browser environments, or in server environments configure the httpIntegration
with the trackIncomingRequestsAsSessions
option set to false
.
Additionally, in Node.js environments, a session was automatically created for every node process when autoSessionTracking
was set to true
. This behavior has been replaced by the processSessionIntegration
which is configured by default.
- The metrics API has been removed from the SDK.
The Sentry metrics beta has ended and the metrics API has been removed from the SDK. Learn more in help center docs.
-
The
@sentry/utils
package has been deprecated. Import everything from@sentry/core
instead. -
Deprecated
AddRequestDataToEventOptions.transaction
. This option effectively doesn't do anything anymore, and will be removed in v9. -
Deprecated
TransactionNamingScheme
type. -
Deprecated
validSeverityLevels
. Will not be replaced. -
Deprecated
urlEncode
. No replacements. -
Deprecated
addRequestDataToEvent
. UsehttpRequestToRequestData
instead and put the resulting object directly onevent.request
. -
Deprecated
extractRequestData
. Instead manually extract relevant data off request. -
Deprecated
arrayify
. No replacements. -
Deprecated
memoBuilder
. No replacements. -
Deprecated
getNumberOfUrlSegments
. No replacements. -
Deprecated
BAGGAGE_HEADER_NAME
. Use the"baggage"
string constant directly instead. -
Deprecated
makeFifoCache
. No replacements. -
Deprecated
dynamicRequire
. No replacements. -
Deprecated
flatten
. No replacements. -
Deprecated
_browserPerformanceTimeOriginMode
. No replacements.
- Deprecated
transactionNamingScheme
option inrequestDataIntegration
. - Deprecated
debugIntegration
. To log outgoing events, use Hook Options (beforeSend
,beforeSendTransaction
, ...). - Deprecated
sessionTimingIntegration
. To capture session durations alongside events, use Context (Sentry.setContext()
). - Deprecated
addTracingHeadersToFetchRequest
method - this was only meant for internal use and is not needed anymore. - Deprecated
generatePropagationContext()
in favor of usinggenerateTraceId()
directly. - Deprecated
spanId
field onpropagationContext
- this field will be removed in v9, and should neither be read or set anymore. - Deprecated
RequestSession
type. No replacements. - Deprecated
RequestSessionStatus
type. No replacements. - Deprecated
SessionFlusherLike
type. No replacements. - Deprecated
SessionFlusher
. No replacements. - Deprecated
initSessionFlusher
onServerRuntimeClient
. No replacements. ThehttpIntegration
will flush sessions by itself.
- Deprecated the
@WithSentry
decorator. Use the@SentryExceptionCaptured
decorator instead. - Deprecated the
SentryTracingInterceptor
method. If you are using@sentry/nestjs
you can safely remove any references to theSentryTracingInterceptor
. If you are using another package migrate to@sentry/nestjs
and remove theSentryTracingInterceptor
afterward. - Deprecated
SentryService
. If you are using@sentry/nestjs
you can safely remove any references to theSentryService
. If you are using another package migrate to@sentry/nestjs
and remove theSentryService
afterward. - Deprecated
SentryGlobalGenericFilter
. Use theSentryGlobalFilter
instead. TheSentryGlobalFilter
is a drop-in replacement. - Deprecated
SentryGlobalGraphQLFilter
. Use theSentryGlobalFilter
instead. TheSentryGlobalFilter
is a drop-in replacement.
-
The
@sentry/types
package has been deprecated. Import everything from@sentry/core
instead. -
Deprecated
Request
in favor ofRequestEventData
. -
Deprecated
RequestSession
. No replacements. -
Deprecated
RequestSessionStatus
. No replacements. -
Deprecated
SessionFlusherLike
. No replacements.
- Deprecated
tracingOptions
inSentry.init()
in favor of passing thevueIntegration()
toSentry.init({ integrations: [...] })
and settingtracingOptions
there.
- Deprecated
tracingOptions
,trackComponents
,timeout
,hooks
options everywhere other than in thetracingOptions
option of thevueIntegration()
.
These options should now be set as follows:
import * as Sentry from '@sentry/vue';
Sentry.init({
integrations: [
Sentry.vueIntegration({
tracingOptions: {
trackComponents: true,
timeout: 1000,
hooks: ['mount', 'update', 'unmount'],
},
}),
],
});
- Deprecated
logErrors
in thevueIntegration
. The Sentry Vue error handler will propagate the error to a user-defined error handler or just re-throw the error (which will log the error without modifying).
- When component tracking is enabled, "update" spans are no longer created by default.
Add an "update"
item to the tracingOptions.hooks
option via the vueIntegration()
to restore this behavior.
Sentry.init({
integrations: [
Sentry.vueIntegration({
tracingOptions: {
trackComponents: true,
hooks: [
'mount',
'update', // <--
'unmount',
],
},
}),
],
});
- Deprecated passing
dsn
,release
,environment
,sampleRate
,tracesSampleRate
,replaysSessionSampleRate
to the integration. Use the runtime-specificSentry.init()
calls for passing these options instead.
- Deprecated
autoInstrumentRemix: false
. The next major version will default to behaving as if this option weretrue
and the option itself will be removed.
- Deprecated
wrapUseRoutes
. Use thewrapUseRoutesV6
orwrapUseRoutesV7
methods instead. - Deprecated
wrapCreateBrowserRouter
. Use thewrapCreateBrowserRouterV6
orwrapCreateBrowserRouterV7
methods instead.
- Deprecated the
hideSourceMaps
option. There are no replacements for this option. The SDK emits hidden sourcemaps by default.
- The
fetchProxyScriptNonce
option insentryHandle()
was deprecated due to security concerns. If you previously specified this option for your CSP policy, specify a script hash in your CSP config or disable the injection of the script entirely.
- Deprecated the
generateSpanContextForPropagationContext
method. There are no replacements for this method.
- Deprecated
processThreadBreadcrumbIntegration
in favor ofchildProcessIntegration
. Functionally they are the same. - Deprecated
nestIntegration
. Use the NestJS SDK (@sentry/nestjs
) instead. - Deprecated
setupNestErrorHandler
. Use the NestJS SDK (@sentry/nestjs
) instead. - Deprecated
addOpenTelemetryInstrumentation
. Use theopenTelemetryInstrumentations
option inSentry.init()
or your custom Sentry Client instead. - Deprecated
registerEsmLoaderHooks.include
andregisterEsmLoaderHooks.exclude
. SetonlyIncludeInstrumentedModules: true
instead. registerEsmLoaderHooks
will only accepttrue | false | undefined
in the future. The SDK will default to wrapping modules that are used as part of OpenTelemetry Instrumentation.httpIntegration({ spans: false })
is configured by default ifskipOpenTelemetrySetup: true
is set. You can still overwrite this if desired.