Claude
Skills
Sign in
Back

sentry-upgrade-migration

Included with Lifetime
$97 forever

Upgrade Sentry SDK versions and migrate breaking API changes. Use when upgrading from Sentry v7 to v8, migrating Python SDK v1 to v2, replacing deprecated Hub/Transaction APIs, or running the migr8 codemod. Trigger: "upgrade sentry", "sentry migration", "sentry breaking changes", "migrate sentry v7 to v8", "update sentry sdk".

Backend & APIssaassentrymigrationupgradesdkbreaking-changes

What this skill does

# Sentry Upgrade Migration

Detect installed Sentry SDK versions, identify breaking API changes, apply automated codemods, and verify the upgrade succeeds with test events and traces.

## Current State

!`npm list 2>/dev/null | command grep @sentry || echo 'No npm Sentry packages found'`
!`pip show sentry-sdk 2>/dev/null | command grep -E '^(Name|Version)' || echo 'No Python sentry-sdk found'`
!`node --version 2>/dev/null || echo 'Node.js not available'`

## Overview

Sentry SDK upgrades require careful handling of breaking API changes. The v7 to v8 JavaScript migration is the most impactful, removing the Hub pattern, replacing Transaction/Span APIs with `startSpan()`, converting class-based integrations to functions, and requiring ESM-first initialization. Python SDK v1 to v2 similarly replaces `configure_scope()` with `get_current_scope()`. This skill automates version detection, runs the official `@sentry/migr8` codemod, applies manual fixes for patterns the codemod misses, and validates the upgrade with test events.

## Prerequisites

- Current Sentry SDK version identified (run DCI above)
- Target version changelog reviewed
- Non-production environment for testing upgrades
- All `@sentry/*` packages at the same major version before starting
- Node.js >= 18.19.0 or >= 20.6.0 for SDK v8 (ESM support required)

## Instructions

### Step 1. Identify Current SDK Version and Scan for Deprecated APIs

```bash
# JavaScript: list all Sentry packages and their versions
npm ls 2>/dev/null | command grep "@sentry/"

# Python: check installed version
pip show sentry-sdk 2>/dev/null

# Verify all @sentry/* packages are the same major version (critical!)
# Mixed versions cause runtime crashes
npm ls @sentry/core @sentry/node @sentry/browser @sentry/utils 2>/dev/null
```

Scan the codebase for deprecated patterns that need migration:

```bash
# Detect v7 Hub usage (removed in v8)
command grep -rn "getCurrentHub\|configureScope\|hub\.capture" src/ --include="*.ts" --include="*.js"

# Detect v7 Transaction API (replaced in v8)
command grep -rn "startTransaction\|\.startChild\|\.finish()" src/ --include="*.ts" --include="*.js"

# Detect class-based integrations (replaced in v8)
command grep -rn "new Sentry\.\|new BrowserTracing\|new Integrations\." src/ --include="*.ts" --include="*.js"

# Detect @sentry/tracing imports (package removed in v8)
command grep -rn "from '@sentry/tracing'" src/ --include="*.ts" --include="*.js"

# Python: detect v1 scope API (replaced in v2)
command grep -rn "configure_scope\|push_scope" src/ --include="*.py"
```

### Step 2. Run the Automated Migration Codemod (JavaScript v7 to v8)

```bash
# First upgrade to latest v7 to get deprecation warnings
npm install @sentry/node@7

# Run the official migr8 codemod — rewrites deprecated APIs automatically
npx @sentry/migr8@latest
# Handles: Hub removal, integration class→function, import path changes
# Does NOT handle: Transaction→startSpan, ESM init pattern, custom transports

# Now upgrade to v8
npm install @sentry/node@8
```

### Step 3. Apply Breaking Change Fixes the Codemod Misses

**Breaking Change: Transaction/Span API replaced with `startSpan()`**

```typescript
// v7 (OLD) — manual transaction lifecycle
const transaction = Sentry.startTransaction({ name: 'process', op: 'task' });
const span = transaction.startChild({ op: 'db.query', description: 'SELECT users' });
// ... do work
span.finish();
transaction.finish();

// v8 (NEW) — callback-based, auto-finishes on return
await Sentry.startSpan({ name: 'process', op: 'task' }, async () => {
  await Sentry.startSpan({ name: 'SELECT users', op: 'db.query' }, async () => {
    // ... do work
  }); // span auto-finishes when callback returns
}); // root span auto-finishes when callback returns
```

**Breaking Change: Hub removed, use Scope API**

```typescript
// v7 (OLD)
const hub = Sentry.getCurrentHub();
hub.configureScope((scope) => {
  scope.setTag('region', 'us-east-1');
});
const transaction = hub.startTransaction({ name: 'my-tx' });

// v8 (NEW)
Sentry.withScope((scope) => {
  scope.setTag('region', 'us-east-1');
});
Sentry.startSpan({ name: 'my-tx', op: 'custom' }, (span) => {
  // work within span
});
```

**Breaking Change: Integrations are functions, not classes**

```typescript
// v7 (OLD)
import * as Sentry from '@sentry/node';
Sentry.init({
  integrations: [new Sentry.Integrations.Http({ tracing: true })],
});

// v8 (NEW) — most integrations are auto-enabled
Sentry.init({
  integrations: [
    Sentry.httpIntegration({ tracing: true }),
  ],
});
```

**Breaking Change: `@sentry/tracing` removed**

```typescript
// v7 (OLD)
import { BrowserTracing } from '@sentry/tracing';
Sentry.init({
  integrations: [new BrowserTracing()],
});

// v8 (NEW) — built into @sentry/browser and @sentry/node
Sentry.init({
  integrations: [
    Sentry.browserTracingIntegration(),
  ],
});
```

**Breaking Change: ESM initialization requires separate file**

```typescript
// v7 (OLD) — init at top of entry file
import * as Sentry from '@sentry/node';
Sentry.init({ dsn: '...' });
// ... app code

// v8 (NEW) — must be in separate file, loaded via --import
// instrument.mjs (separate file)
import * as Sentry from '@sentry/node';
Sentry.init({ dsn: '...' });

// Run with: node --import ./instrument.mjs app.mjs
// Or in package.json: "start": "node --import ./instrument.mjs app.mjs"
```

**Breaking Change: Custom transport must return response**

```typescript
// v7 (OLD) — send could return void
makeRequest(request) {
  sendToBackend(request);
}

// v8 (NEW) — must return TransportMakeRequestResponse
makeRequest(request) {
  sendToBackend(request);
  return { statusCode: 200 };
}
```

See [major-version-migrations.md](references/major-version-migrations.md) for v6-to-v7 and Python v1-to-v2 migration details.

### Step 4. Python SDK v1 to v2 Migration

```python
# v1 (OLD) — configure_scope / push_scope
import sentry_sdk

with sentry_sdk.configure_scope() as scope:
    scope.set_tag("key", "value")

with sentry_sdk.push_scope() as scope:
    scope.set_extra("debug_info", data)
    sentry_sdk.capture_message("scoped message")

# v2 (NEW) — get_current_scope / new_scope
import sentry_sdk

scope = sentry_sdk.get_current_scope()
scope.set_tag("key", "value")

with sentry_sdk.new_scope() as scope:
    scope.set_extra("debug_info", data)
    sentry_sdk.capture_message("scoped message")
```

```bash
# Upgrade Python SDK
pip install --upgrade sentry-sdk

# Verify version
python -c "import sentry_sdk; print(sentry_sdk.VERSION)"
```

### Step 5. Align All Package Versions and Update Bundler Plugins

```bash
# All @sentry/* packages MUST be the same major version
# Mixed versions cause "Cannot read properties of undefined" runtime errors
npm install @sentry/node@8 @sentry/browser@8 @sentry/react@8 @sentry/profiling-node@8

# Remove deprecated packages
npm uninstall @sentry/tracing @sentry/hub 2>/dev/null

# Update bundler plugins (must be v2.14.2+ for SDK v8 compatibility)
npm install @sentry/webpack-plugin@latest @sentry/vite-plugin@latest 2>/dev/null
```

### Step 6. Verify the Upgrade with Test Events

```typescript
// test-migration.mjs — run after upgrading
import * as Sentry from '@sentry/node';

async function verifyUpgrade() {
  console.log('SDK Version:', Sentry.SDK_VERSION);

  // 1. Test error capture
  try {
    throw new Error('Migration verification error');
  } catch (e) {
    const eventId = Sentry.captureException(e);
    console.log('Error captured:', eventId ? 'PASS' : 'FAIL');
  }

  // 2. Test scoped context (v8 API)
  Sentry.withScope((scope) => {
    scope.setTag('test', 'migration-verify');
    scope.setUser({ id: 'test-user' });
    Sentry.captureMessage('Scoped context test');
  });
  console.log('Scoped context: PASS');

  // 3. Test performance span (v8 API — replaces startTransaction)
  await Sentry.startSpan(
    { name: 'migration-verify', op: 'test' },
    async (span) => {
      await Sentry.startSpan(
        { name: 'child-opera

Related in Backend & APIs