--- name: sentry-upgrade-migration description: '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". ' allowed-tools: Read, Write, Edit, Bash(npm:*), Bash(npx:*), Bash(pip:*), Bash(node:*), Grep, Glob version: 1.0.0 license: MIT author: Jeremy Longshore tags: - saas - sentry - migration - upgrade - sdk - breaking-changes compatibility: Designed for Claude Code, also compatible with Codex and OpenClaw --- # 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-operation', op: 'test.child' }, async () => { await new Promise((r) => setTimeout(r, 50)); } ); console.log('Span created:', span ? 'PASS' : 'FAIL'); } ); // 4. Test breadcrumbs Sentry.addBreadcrumb({ category: 'test', message: 'Migration breadcrumb', level: 'info', }); console.log('Breadcrumb: PASS'); // 5. Flush and verify delivery const flushed = await Sentry.flush(5000); console.log('Flush:', flushed ? 'PASS' : 'FAIL'); } verifyUpgrade(); ``` See [testing-after-upgrade.md](references/testing-after-upgrade.md) for the full verification checklist. ### Step 7. Gradual Rollout Strategy 1. Upgrade in development environment, run full test suite 2. Watch for `Sentry.startTransaction is not a function` or similar runtime errors 3. Deploy to staging, monitor Sentry dashboard for 1-2 days 4. Check source maps still resolve (re-upload if bundler plugin changed) 5. Verify trace propagation between services (check `sentry-trace` header) 6. Deploy to production with rollback plan ready ## Output - SDK upgraded to target version with all `@sentry/*` packages aligned - Deprecated APIs migrated: Hub removed, Transaction replaced with `startSpan()`, integrations converted to functions - ESM initialization pattern applied (separate `instrument.mjs` file) - `@sentry/tracing` package removed (functionality built into core packages) - Bundler plugins updated to v2.14.2+ - Post-migration test events captured successfully in Sentry dashboard - Source maps verified, traces propagating across services ## Error Handling | Error | Cause | Solution | |-------|-------|----------| | `Cannot find module '@sentry/hub'` | Package removed in v8 | Replace hub imports with `@sentry/node` scope APIs | | `Sentry.startTransaction is not a function` | API removed in v8 | Use `Sentry.startSpan()` callback pattern instead | | `new Integrations.X is not a constructor` | Classes removed in v8 | Use functional form: `Sentry.xIntegration()` | | `Cannot find module '@sentry/tracing'` | Package removed in v8 | Remove import; tracing is built into `@sentry/node` v8 | | Mixed version runtime crash | Some `@sentry/*` at v7, others at v8 | Align all packages: `npm install @sentry/node@8 @sentry/browser@8` | | `ERR_MODULE_NOT_FOUND` on startup | ESM init file missing or wrong path | Create `instrument.mjs`, run with `node --import ./instrument.mjs` | | Source maps not resolving | Bundler plugin version incompatible | Update `@sentry/webpack-plugin` or `@sentry/vite-plugin` to v2.14.2+ | | Python `AttributeError: configure_scope` | API removed in Python SDK v2 | Use `sentry_sdk.get_current_scope()` instead | | `Transport.send must return object` | Custom transport missing return | Return `{ statusCode: 200 }` from `makeRequest()` | | Node.js version error | SDK v8 requires Node 18.19+ or 20.6+ | Upgrade Node.js: `nvm install 20 && nvm use 20` | See [errors.md](references/errors.md) for additional error patterns. ## Examples **Example 1: Full v7 to v8 JavaScript Migration** Request: "Upgrade our Express app from Sentry v7 to v8" ```bash # Detect current state npm ls 2>/dev/null | command grep "@sentry/" # @sentry/node@7.114.0 # @sentry/tracing@7.114.0 # Run codemod npx @sentry/migr8@latest # Upgrade packages npm install @sentry/node@8 npm uninstall @sentry/tracing ``` Before (v7 Express setup): ```typescript import * as Sentry from '@sentry/node'; import { Integrations } from '@sentry/tracing'; Sentry.init({ dsn: process.env.SENTRY_DSN, integrations: [new Integrations.Express({ app })], tracesSampleRate: 0.2, }); app.use(Sentry.Handlers.requestHandler()); app.use(Sentry.Handlers.tracingHandler()); // ... routes app.use(Sentry.Handlers.errorHandler()); ``` After (v8 Express setup): ```typescript // instrument.mjs — must be separate file import * as Sentry from '@sentry/node'; Sentry.init({ dsn: process.env.SENTRY_DSN, tracesSampleRate: 0.2, }); // app.mjs — run with: node --import ./instrument.mjs app.mjs import express from 'express'; import * as Sentry from '@sentry/node'; const app = express(); // v8: Sentry auto-instruments Express — no manual handlers needed // Sentry.Handlers.requestHandler() and tracingHandler() are removed // Error handler replaced with Sentry.setupExpressErrorHandler() Sentry.setupExpressErrorHandler(app); app.listen(3000); ``` Result: SDK upgraded to v8.49.0, `@sentry/tracing` removed, Express auto-instrumented, source maps verified, test error captured in dashboard. **Example 2: Python v1 to v2 Migration** Request: "Upgrade sentry-sdk from 1.x to 2.x in our Flask app" ```python # Before (v1) import sentry_sdk from sentry_sdk.integrations.flask import FlaskIntegration sentry_sdk.init( dsn="...", integrations=[FlaskIntegration()], ) with sentry_sdk.configure_scope() as scope: scope.set_tag("deploy", "v2.1") # After (v2) import sentry_sdk from sentry_sdk.integrations.flask import FlaskIntegration sentry_sdk.init( dsn="...", integrations=[FlaskIntegration()], ) scope = sentry_sdk.get_current_scope() scope.set_tag("deploy", "v2.1") ``` Result: SDK upgraded to 2.x, `configure_scope` replaced with `get_current_scope`, `push_scope` replaced with `new_scope`, Flask integration unchanged, test error captured. ## Resources - [JavaScript v7 to v8 Migration Guide](https://docs.sentry.io/platforms/javascript/migration/v7-to-v8/) - [Node.js v7 to v8 Guide](https://docs.sentry.io/platforms/javascript/guides/node/migration/v7-to-v8/) - [Express v7 to v8 Guide](https://docs.sentry.io/platforms/javascript/guides/express/migration/v7-to-v8/) - [Python SDK v1 to v2 Migration](https://docs.sentry.io/platforms/python/migration/1.x-to-2.x/) - [@sentry/migr8 Codemod Tool](https://github.com/getsentry/sentry-migr8) - [Sentry SDK Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md) ## Next Steps - Run sentry-performance-tracing to configure v8 span-based tracing - Run sentry-ci-integration to update CI source map upload after SDK change - Run sentry-release-management to tag the upgraded release - Run sentry-known-pitfalls to review common post-upgrade issues