From f5135e7b07a7bce655765153455fb933d78b79eb Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Mon, 2 Feb 2026 12:05:08 -0500 Subject: [PATCH 01/22] chore: initial config and rule setup --- docs/oxlint-migration-gaps.md | 145 ++++++++++++++++++++++++++++++++++ nx.json | 2 +- 2 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 docs/oxlint-migration-gaps.md diff --git a/docs/oxlint-migration-gaps.md b/docs/oxlint-migration-gaps.md new file mode 100644 index 000000000000..7893e4c94261 --- /dev/null +++ b/docs/oxlint-migration-gaps.md @@ -0,0 +1,145 @@ +# Oxlint Migration Gaps + +This document tracks the ESLint rules that are not natively supported in Oxlint, or have different behavior. + +## Migration Summary + +| Metric | Value | +| ----------------------- | ----------------------------------------- | +| ESLint Version | 8.57.0 | +| Oxlint Version | 1.43.0 | +| Performance Improvement | ~330x faster (24ms vs ~8s for same files) | +| Total Files Linted | 1953 | +| Rules Active | 93+ | + +## Unsupported ESLint Plugins/Rules + +### @typescript-eslint Rules Not Supported + +| Rule | Status | Notes | +| -------------------------------------------------- | ---------- | ------------------------------------------ | +| `@typescript-eslint/no-inferrable-types` | Not needed | Was disabled in ESLint config | +| `@typescript-eslint/typedef` | **Gap** | Enforces type annotations on variables | +| `@typescript-eslint/member-ordering` | **Gap** | Class member ordering enforcement | +| `@typescript-eslint/naming-convention` | **Gap** | Private/protected member underscore prefix | +| `@typescript-eslint/unified-signatures` | **Gap** | Prevent unnecessary overloads | +| `@typescript-eslint/explicit-member-accessibility` | **Gap** | public/private/protected keywords | + +### eslint-plugin-deprecation + +| Rule | Status | Notes | +| ------------------------- | ------- | --------------------------------------------------- | +| `deprecation/deprecation` | Partial | Use `typescript/no-deprecated` with type-aware mode | + +### eslint-plugin-import + +| Rule | Status | Notes | +| ----------------------------------- | ------- | --------------------------------- | +| `import/no-extraneous-dependencies` | **Gap** | Check for undeclared dependencies | +| `import/first` | **Gap** | Imports should come first | +| `import/newline-after-import` | **Gap** | Newline after import block | + +### eslint-plugin-simple-import-sort + +| Rule | Status | Notes | +| ---------------------------- | ------- | -------------------------------------------------- | +| `simple-import-sort/imports` | **Gap** | Import sorting - consider using Prettier or dprint | + +### eslint-plugin-jsdoc + +| Rule | Status | Notes | +| --------------------- | ------- | ----------------------------- | +| `jsdoc/require-jsdoc` | **Gap** | Require JSDoc for public APIs | + +### ESLint Core Rules + +| Rule | Status | Notes | +| ----------------------- | ------- | ------------------------------------------- | +| `max-lines` | **Gap** | File size limit (300 lines) | +| `spaced-comment` | **Gap** | Whitespace in comments | +| `no-restricted-globals` | **Gap** | Restrict window/document/location/navigator | + +## Custom Sentry Plugin Rules + +The `@sentry-internal/eslint-plugin-sdk` contains 6 custom rules. These can be loaded via Oxlint's JS plugins feature. + +| Rule | Status | Notes | +| ----------------------------- | ----------- | ----------------------------------------------- | +| `no-eq-empty` | **Gap** | Disallow `=== []` or `=== {}` | +| `no-class-field-initializers` | **Gap** | Disallow class field initializers (bundle size) | +| `no-regexp-constructor` | **Gap** | Warn about `new RegExp()` usage | +| `no-unsafe-random-apis` | **Gap** | Disallow `Math.random()` etc | +| `no-focused-tests` | **Covered** | Use `jest/no-focused-tests` | +| `no-skipped-tests` | **Covered** | Use `jest/no-disabled-tests` | + +## Type-Aware Linting + +Type-aware rules require the `--type-aware` flag and `oxlint-tsgolint` package: + +```bash +# Install type-aware package +yarn add -D oxlint-tsgolint + +# Run with type-aware rules +yarn lint:oxlint:type-aware +``` + +Type-aware mode enables additional checks like: + +- `typescript/no-floating-promises` (enhanced) +- `typescript/no-unsafe-member-access` (enhanced) +- `typescript/unbound-method` (enhanced) +- `typescript/no-deprecated` +- `typescript/no-base-to-string` +- `typescript/restrict-template-expressions` + +**Note**: Type-aware linting requires TypeScript 7+ and may need tsconfig adjustments. + +## Current Errors Found by Oxlint + +As of migration, Oxlint identifies the following issues that ESLint may not have caught: + +### Complexity Issues (21 functions) + +Functions exceeding cyclomatic complexity of 20: + +- `getNotificationAttributes` (31) +- `constructor` in replay integration (32) +- `xhrCallback` (27) +- `_INTERNAL_captureLog` (28) +- And others... + +### Unused Variables + +- Unused catch parameters not prefixed with `_` +- Unused function declarations + +### Code Quality + +- Bitwise operations (intentionally used in replay packages) +- Missing return types on some callback functions + +## Recommendations + +1. **JS Plugins**: Load the custom Sentry plugin via `jsPlugins` config option +2. **Prettier Integration**: Use Prettier for import sorting since `simple-import-sort` is not supported +3. **Type-Aware**: Enable type-aware linting in CI for enhanced TypeScript checks +4. **Fix Incrementally**: Address the 71+ errors found by Oxlint over time + +## Performance Comparison + +``` +ESLint (packages/core + packages/browser): + Time: ~8 seconds + +Oxlint (same files): + Time: 24ms + Speedup: ~330x +``` + +## References + +- [Oxlint Documentation](https://oxc.rs/docs/guide/usage/linter/) +- [Migrate from ESLint](https://oxc.rs/docs/guide/usage/linter/migrate-from-eslint.html) +- [Type-Aware Linting](https://oxc.rs/docs/guide/usage/linter/type-aware.html) +- [JS Plugins](https://oxc.rs/docs/guide/usage/linter/js-plugins.html) diff --git a/nx.json b/nx.json index 7cd807e089fb..5cc18211d58b 100644 --- a/nx.json +++ b/nx.json @@ -51,7 +51,7 @@ "inputs": ["default"], "dependsOn": ["^build:types", "build:types"], "outputs": [], - "cache": true + "cache": false }, "test:unit": { "dependsOn": ["build:types", "^build:types", "build:transpile", "^build:transpile"], From a722d549e0d4469bdfa8f4c38bf9ed65a72b35d1 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Mon, 2 Feb 2026 13:41:42 -0500 Subject: [PATCH 02/22] chore: cleanup eslint --- docs/oxlint-migration-gaps.md | 145 ---------------------------------- 1 file changed, 145 deletions(-) delete mode 100644 docs/oxlint-migration-gaps.md diff --git a/docs/oxlint-migration-gaps.md b/docs/oxlint-migration-gaps.md deleted file mode 100644 index 7893e4c94261..000000000000 --- a/docs/oxlint-migration-gaps.md +++ /dev/null @@ -1,145 +0,0 @@ -# Oxlint Migration Gaps - -This document tracks the ESLint rules that are not natively supported in Oxlint, or have different behavior. - -## Migration Summary - -| Metric | Value | -| ----------------------- | ----------------------------------------- | -| ESLint Version | 8.57.0 | -| Oxlint Version | 1.43.0 | -| Performance Improvement | ~330x faster (24ms vs ~8s for same files) | -| Total Files Linted | 1953 | -| Rules Active | 93+ | - -## Unsupported ESLint Plugins/Rules - -### @typescript-eslint Rules Not Supported - -| Rule | Status | Notes | -| -------------------------------------------------- | ---------- | ------------------------------------------ | -| `@typescript-eslint/no-inferrable-types` | Not needed | Was disabled in ESLint config | -| `@typescript-eslint/typedef` | **Gap** | Enforces type annotations on variables | -| `@typescript-eslint/member-ordering` | **Gap** | Class member ordering enforcement | -| `@typescript-eslint/naming-convention` | **Gap** | Private/protected member underscore prefix | -| `@typescript-eslint/unified-signatures` | **Gap** | Prevent unnecessary overloads | -| `@typescript-eslint/explicit-member-accessibility` | **Gap** | public/private/protected keywords | - -### eslint-plugin-deprecation - -| Rule | Status | Notes | -| ------------------------- | ------- | --------------------------------------------------- | -| `deprecation/deprecation` | Partial | Use `typescript/no-deprecated` with type-aware mode | - -### eslint-plugin-import - -| Rule | Status | Notes | -| ----------------------------------- | ------- | --------------------------------- | -| `import/no-extraneous-dependencies` | **Gap** | Check for undeclared dependencies | -| `import/first` | **Gap** | Imports should come first | -| `import/newline-after-import` | **Gap** | Newline after import block | - -### eslint-plugin-simple-import-sort - -| Rule | Status | Notes | -| ---------------------------- | ------- | -------------------------------------------------- | -| `simple-import-sort/imports` | **Gap** | Import sorting - consider using Prettier or dprint | - -### eslint-plugin-jsdoc - -| Rule | Status | Notes | -| --------------------- | ------- | ----------------------------- | -| `jsdoc/require-jsdoc` | **Gap** | Require JSDoc for public APIs | - -### ESLint Core Rules - -| Rule | Status | Notes | -| ----------------------- | ------- | ------------------------------------------- | -| `max-lines` | **Gap** | File size limit (300 lines) | -| `spaced-comment` | **Gap** | Whitespace in comments | -| `no-restricted-globals` | **Gap** | Restrict window/document/location/navigator | - -## Custom Sentry Plugin Rules - -The `@sentry-internal/eslint-plugin-sdk` contains 6 custom rules. These can be loaded via Oxlint's JS plugins feature. - -| Rule | Status | Notes | -| ----------------------------- | ----------- | ----------------------------------------------- | -| `no-eq-empty` | **Gap** | Disallow `=== []` or `=== {}` | -| `no-class-field-initializers` | **Gap** | Disallow class field initializers (bundle size) | -| `no-regexp-constructor` | **Gap** | Warn about `new RegExp()` usage | -| `no-unsafe-random-apis` | **Gap** | Disallow `Math.random()` etc | -| `no-focused-tests` | **Covered** | Use `jest/no-focused-tests` | -| `no-skipped-tests` | **Covered** | Use `jest/no-disabled-tests` | - -## Type-Aware Linting - -Type-aware rules require the `--type-aware` flag and `oxlint-tsgolint` package: - -```bash -# Install type-aware package -yarn add -D oxlint-tsgolint - -# Run with type-aware rules -yarn lint:oxlint:type-aware -``` - -Type-aware mode enables additional checks like: - -- `typescript/no-floating-promises` (enhanced) -- `typescript/no-unsafe-member-access` (enhanced) -- `typescript/unbound-method` (enhanced) -- `typescript/no-deprecated` -- `typescript/no-base-to-string` -- `typescript/restrict-template-expressions` - -**Note**: Type-aware linting requires TypeScript 7+ and may need tsconfig adjustments. - -## Current Errors Found by Oxlint - -As of migration, Oxlint identifies the following issues that ESLint may not have caught: - -### Complexity Issues (21 functions) - -Functions exceeding cyclomatic complexity of 20: - -- `getNotificationAttributes` (31) -- `constructor` in replay integration (32) -- `xhrCallback` (27) -- `_INTERNAL_captureLog` (28) -- And others... - -### Unused Variables - -- Unused catch parameters not prefixed with `_` -- Unused function declarations - -### Code Quality - -- Bitwise operations (intentionally used in replay packages) -- Missing return types on some callback functions - -## Recommendations - -1. **JS Plugins**: Load the custom Sentry plugin via `jsPlugins` config option -2. **Prettier Integration**: Use Prettier for import sorting since `simple-import-sort` is not supported -3. **Type-Aware**: Enable type-aware linting in CI for enhanced TypeScript checks -4. **Fix Incrementally**: Address the 71+ errors found by Oxlint over time - -## Performance Comparison - -``` -ESLint (packages/core + packages/browser): - Time: ~8 seconds - -Oxlint (same files): - Time: 24ms - Speedup: ~330x -``` - -## References - -- [Oxlint Documentation](https://oxc.rs/docs/guide/usage/linter/) -- [Migrate from ESLint](https://oxc.rs/docs/guide/usage/linter/migrate-from-eslint.html) -- [Type-Aware Linting](https://oxc.rs/docs/guide/usage/linter/type-aware.html) -- [JS Plugins](https://oxc.rs/docs/guide/usage/linter/js-plugins.html) From b1d889a78725db030ed8695e679feabe026c3191 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Thu, 19 Feb 2026 11:24:21 -0500 Subject: [PATCH 03/22] chore: renable no floating promises --- .oxlintrc.json | 3 +-- packages/deno/src/utils/streaming.ts | 1 + .../react/src/reactrouter-compat-utils/instrumentation.tsx | 1 + packages/replay-internal/src/coreHandlers/handleHistory.ts | 1 + .../src/coreHandlers/util/addNetworkBreadcrumb.ts | 1 + 5 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.oxlintrc.json b/.oxlintrc.json index 6a11fcc33977..118e9815210a 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -61,7 +61,7 @@ "typescript/consistent-type-imports": "error", "typescript/no-unnecessary-type-assertion": "error", "typescript/prefer-for-of": "error", - // "typescript/no-floating-promises": ["error", { "ignoreVoid": false }], + "typescript/no-floating-promises": ["error", { "ignoreVoid": true }], "typescript/no-dynamic-delete": "error", // "typescript/no-unsafe-member-access": "error", "typescript/unbound-method": "error", @@ -70,7 +70,6 @@ // === FIXME: Rules to turn back as error === "typescript/prefer-optional-chain": "warn", - "typescript/no-floating-promises": "warn", "typescript/no-unsafe-member-access": "warn" } }, diff --git a/packages/deno/src/utils/streaming.ts b/packages/deno/src/utils/streaming.ts index b999af39bf49..4f6f4654af68 100644 --- a/packages/deno/src/utils/streaming.ts +++ b/packages/deno/src/utils/streaming.ts @@ -81,6 +81,7 @@ function monitorStream( onDone: () => void, ): ReadableStream> { const reader = stream.getReader(); + // oxlint-disable-next-line typescript/no-floating-promises reader.closed.finally(() => onDone()); return new ReadableStream({ async start(controller) { diff --git a/packages/react/src/reactrouter-compat-utils/instrumentation.tsx b/packages/react/src/reactrouter-compat-utils/instrumentation.tsx index 5725309ff12b..e73438312676 100644 --- a/packages/react/src/reactrouter-compat-utils/instrumentation.tsx +++ b/packages/react/src/reactrouter-compat-utils/instrumentation.tsx @@ -249,6 +249,7 @@ function trackLazyRouteLoad(span: Span, promise: Promise): void { promises.add(promise); // Clean up when promise resolves/rejects + // oxlint-disable-next-line typescript/no-floating-promises promise.finally(() => { const currentPromises = pendingLazyRouteLoads.get(span); if (currentPromises) { diff --git a/packages/replay-internal/src/coreHandlers/handleHistory.ts b/packages/replay-internal/src/coreHandlers/handleHistory.ts index e12c65745914..aa85757e3a3e 100644 --- a/packages/replay-internal/src/coreHandlers/handleHistory.ts +++ b/packages/replay-internal/src/coreHandlers/handleHistory.ts @@ -38,6 +38,7 @@ export function handleHistorySpanListener(replay: ReplayContainer): (handlerData replay.triggerUserActivity(); replay.addUpdate(() => { + // oxlint-disable-next-line typescript/no-floating-promises createPerformanceSpans(replay, [result]); // Returning false to flush return false; diff --git a/packages/replay-internal/src/coreHandlers/util/addNetworkBreadcrumb.ts b/packages/replay-internal/src/coreHandlers/util/addNetworkBreadcrumb.ts index b67b27e6ab7f..38a19d1030f9 100644 --- a/packages/replay-internal/src/coreHandlers/util/addNetworkBreadcrumb.ts +++ b/packages/replay-internal/src/coreHandlers/util/addNetworkBreadcrumb.ts @@ -20,6 +20,7 @@ export function addNetworkBreadcrumb( } replay.addUpdate(() => { + // oxlint-disable-next-line typescript/no-floating-promises createPerformanceSpans(replay, [result]); // Returning true will cause `addUpdate` to not flush // We do not want network requests to cause a flush. This will prevent From cef9a2566a0563a820889f5efff88e983dfb1db7 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Thu, 19 Feb 2026 11:52:38 -0500 Subject: [PATCH 04/22] chore: re-enable prefer-optional-chain --- .oxlintrc.json | 5 +++-- packages/angular/src/errorhandler.ts | 2 ++ packages/angular/src/zone.ts | 2 +- packages/astro/src/integration/snippets.ts | 2 ++ packages/browser/src/eventbuilder.ts | 1 + packages/browser/src/stack-parsers.ts | 2 +- packages/browser/src/tracing/browserTracingIntegration.ts | 3 +-- packages/core/src/client.ts | 1 + packages/core/src/integrations/mcp-server/transport.ts | 1 + packages/core/src/tracing/google-genai/index.ts | 1 + packages/core/src/tracing/openai/utils.ts | 1 + packages/core/src/tracing/vercel-ai/index.ts | 2 +- packages/core/src/utils/prepareEvent.ts | 1 + packages/nextjs/src/client/clientNormalizationIntegration.ts | 2 +- .../nextjs/src/common/devErrorSymbolicationEventProcessor.ts | 1 + .../src/integrations/local-variables/local-variables-sync.ts | 1 + .../node-core/src/integrations/local-variables/worker.ts | 1 + packages/node-core/src/utils/detection.ts | 1 + packages/react/src/hoist-non-react-statics.ts | 2 +- .../react/src/reactrouter-compat-utils/instrumentation.tsx | 4 ++-- .../react/src/reactrouter-compat-utils/route-manifest.ts | 2 +- packages/remix/src/client/performance.tsx | 2 +- .../replay-internal/src/coreHandlers/handleAfterSendEvent.ts | 2 +- packages/replay-internal/src/replay.ts | 3 +-- packages/replay-internal/src/util/handleRecordingEmit.ts | 2 +- packages/sveltekit/src/server-common/handle.ts | 1 + 26 files changed, 31 insertions(+), 17 deletions(-) diff --git a/.oxlintrc.json b/.oxlintrc.json index 118e9815210a..484b222da30b 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -67,9 +67,9 @@ "typescript/unbound-method": "error", "typescript/no-explicit-any": "error", "typescript/no-empty-function": "off", + "typescript/prefer-optional-chain": ["error"], // === FIXME: Rules to turn back as error === - "typescript/prefer-optional-chain": "warn", "typescript/no-unsafe-member-access": "warn" } }, @@ -110,7 +110,8 @@ "typescript/no-floating-promises": "off", "typescript/unbound-method": "off", "max-lines": "off", - "complexity": "off" + "complexity": "off", + "typescript/prefer-optional-chain": "off" } }, { diff --git a/packages/angular/src/errorhandler.ts b/packages/angular/src/errorhandler.ts index ceb05c0b9e9f..ccd918667f00 100644 --- a/packages/angular/src/errorhandler.ts +++ b/packages/angular/src/errorhandler.ts @@ -26,6 +26,7 @@ export interface ErrorHandlerOptions { function tryToUnwrapZonejsError(error: unknown): unknown | Error { // TODO: once Angular14 is the minimum requirement ERROR_ORIGINAL_ERROR and // getOriginalError from error.ts can be used directly. + // oxlint-disable-next-line typescript/prefer-optional-chain return error && (error as { ngOriginalError: Error }).ngOriginalError ? (error as { ngOriginalError: Error }).ngOriginalError : error; @@ -39,6 +40,7 @@ function extractHttpModuleError(error: HttpErrorResponse): string | Error { // ... or an`ErrorEvent`, which can provide us with the message but no stack... // guarding `ErrorEvent` against `undefined` as it's not defined in Node environments + // oxlint-disable-next-line typescript/prefer-optional-chain if (typeof ErrorEvent !== 'undefined' && error.error instanceof ErrorEvent && error.error.message) { return error.error.message; } diff --git a/packages/angular/src/zone.ts b/packages/angular/src/zone.ts index 22f56e4c3871..fb4db2ed8ac2 100644 --- a/packages/angular/src/zone.ts +++ b/packages/angular/src/zone.ts @@ -7,7 +7,7 @@ declare const Zone: any; // In Angular 17 and future versions, zoneless support is forthcoming. // Therefore, it's advisable to safely check whether the `run` function is // available in the `` context. -// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access +// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access typescript/prefer-optional-chain const isNgZoneEnabled = typeof Zone !== 'undefined' && Zone.root?.run; /** diff --git a/packages/astro/src/integration/snippets.ts b/packages/astro/src/integration/snippets.ts index 82278da28925..c97ca2fd1ed0 100644 --- a/packages/astro/src/integration/snippets.ts +++ b/packages/astro/src/integration/snippets.ts @@ -59,6 +59,7 @@ const buildClientIntegrations = (options: SentryOptions): string => { integrations.push('Sentry.browserTracingIntegration()'); } + /* oxlint-disable typescript/prefer-optional-chain */ if ( options.replaysSessionSampleRate == null || options.replaysSessionSampleRate || @@ -67,6 +68,7 @@ const buildClientIntegrations = (options: SentryOptions): string => { ) { integrations.push('Sentry.replayIntegration()'); } + /* oxlint-enable typescript/prefer-optional-chain */ return integrations.join(', '); }; diff --git a/packages/browser/src/eventbuilder.ts b/packages/browser/src/eventbuilder.ts index 9823d596a502..798a068b5adf 100644 --- a/packages/browser/src/eventbuilder.ts +++ b/packages/browser/src/eventbuilder.ts @@ -165,6 +165,7 @@ function getPopFirstTopFrames(ex: Error & { framesToPop?: unknown }): number { function isWebAssemblyException(exception: unknown): exception is WebAssembly.Exception { // Check for support // @ts-expect-error - WebAssembly.Exception is a valid class + // oxlint-disable-next-line typescript/prefer-optional-chain if (typeof WebAssembly !== 'undefined' && typeof WebAssembly.Exception !== 'undefined') { // @ts-expect-error - WebAssembly.Exception is a valid class return exception instanceof WebAssembly.Exception; diff --git a/packages/browser/src/stack-parsers.ts b/packages/browser/src/stack-parsers.ts index 02c3a1f66af3..cb74bc1e6ce6 100644 --- a/packages/browser/src/stack-parsers.ts +++ b/packages/browser/src/stack-parsers.ts @@ -88,7 +88,7 @@ const chromeStackParserFn: StackLineParserFn = line => { const parts = chromeRegex.exec(line) as null | [string, string, string, string, string]; if (parts) { - const isEval = parts[2] && parts[2].indexOf('eval') === 0; // start of line + const isEval = parts[2]?.indexOf('eval') === 0; // start of line if (isEval) { const subMatch = chromeEvalRegex.exec(parts[2]) as null | [string, string, string, string]; diff --git a/packages/browser/src/tracing/browserTracingIntegration.ts b/packages/browser/src/tracing/browserTracingIntegration.ts index 2c5426aab783..b6dc8b2e92b8 100644 --- a/packages/browser/src/tracing/browserTracingIntegration.ts +++ b/packages/browser/src/tracing/browserTracingIntegration.ts @@ -526,8 +526,7 @@ export const browserTracingIntegration = ((options: Partial { throw _makeDoNotSendEventError('An event processor returned `null`, will not send event.'); } + // oxlint-disable-next-line typescript/prefer-optional-chain const isInternalException = hint.data && (hint.data as { __sentry__: boolean }).__sentry__ === true; if (isInternalException) { return prepared; diff --git a/packages/core/src/integrations/mcp-server/transport.ts b/packages/core/src/integrations/mcp-server/transport.ts index 5e4fd6e75c23..065fb44ab17d 100644 --- a/packages/core/src/integrations/mcp-server/transport.ts +++ b/packages/core/src/integrations/mcp-server/transport.ts @@ -105,6 +105,7 @@ export function wrapTransportSend(transport: MCPTransport, options: ResolvedMcpO } if (isJsonRpcResponse(message)) { + // oxlint-disable-next-line typescript/prefer-optional-chain if (message.id !== null && message.id !== undefined) { if (message.error) { captureJsonRpcErrorResponse(message.error); diff --git a/packages/core/src/tracing/google-genai/index.ts b/packages/core/src/tracing/google-genai/index.ts index 7781b67d6db0..369fb7701bd9 100644 --- a/packages/core/src/tracing/google-genai/index.ts +++ b/packages/core/src/tracing/google-genai/index.ts @@ -143,6 +143,7 @@ function addPrivateRequestAttributes(span: Span, params: Record // config.systemInstruction: ContentUnion if ( + // oxlint-disable-next-line typescript/prefer-optional-chain 'config' in params && params.config && typeof params.config === 'object' && diff --git a/packages/core/src/tracing/openai/utils.ts b/packages/core/src/tracing/openai/utils.ts index 82494f7ae018..3338d4524d75 100644 --- a/packages/core/src/tracing/openai/utils.ts +++ b/packages/core/src/tracing/openai/utils.ts @@ -222,6 +222,7 @@ export function addResponsesApiAttributes(span: Span, response: OpenAIResponseOb // Filter for function_call type objects in the output array const functionCalls = responseWithOutput.output.filter( (item): unknown => + // oxlint-disable-next-line typescript/prefer-optional-chain typeof item === 'object' && item !== null && (item as Record).type === 'function_call', ); diff --git a/packages/core/src/tracing/vercel-ai/index.ts b/packages/core/src/tracing/vercel-ai/index.ts index 919c06eb12d6..f6fbee6d68f5 100644 --- a/packages/core/src/tracing/vercel-ai/index.ts +++ b/packages/core/src/tracing/vercel-ai/index.ts @@ -135,7 +135,7 @@ function vercelAiEventProcessor(event: Event): Event { // Also apply to root when it is the invoke_agent pipeline const trace = event.contexts?.trace; - if (trace && trace.op === 'gen_ai.invoke_agent') { + if (trace?.op === 'gen_ai.invoke_agent') { applyAccumulatedTokens(trace, tokenAccumulator); } } diff --git a/packages/core/src/utils/prepareEvent.ts b/packages/core/src/utils/prepareEvent.ts index 6528873c3dee..95e244df2092 100644 --- a/packages/core/src/utils/prepareEvent.ts +++ b/packages/core/src/utils/prepareEvent.ts @@ -95,6 +95,7 @@ export function prepareEvent( ]; // Skip event processors for internal exceptions to prevent recursion + // oxlint-disable-next-line typescript/prefer-optional-chain const isInternalException = hint.data && (hint.data as { __sentry__: boolean }).__sentry__ === true; const result = isInternalException ? resolvedSyncPromise(prepared) diff --git a/packages/nextjs/src/client/clientNormalizationIntegration.ts b/packages/nextjs/src/client/clientNormalizationIntegration.ts index c92147c82bbe..30c57ee8fc02 100644 --- a/packages/nextjs/src/client/clientNormalizationIntegration.ts +++ b/packages/nextjs/src/client/clientNormalizationIntegration.ts @@ -18,7 +18,7 @@ export const nextjsClientStackFrameNormalizationIntegration = defineIntegration( iteratee: frame => { if (experimentalThirdPartyOriginStackFrames) { // Not sure why but access to global WINDOW from @sentry/Browser causes hideous ci errors - // eslint-disable-next-line no-restricted-globals + // oxlint-disable-next-line typescript/prefer-optional-chain no-restricted-globals const windowOrigin = typeof window !== 'undefined' && window.location ? window.location.origin : ''; // A filename starting with the local origin and not ending with JS is most likely JS in HTML which we do not want to rewrite if (frame.filename?.startsWith(windowOrigin) && !frame.filename.endsWith('.js')) { diff --git a/packages/nextjs/src/common/devErrorSymbolicationEventProcessor.ts b/packages/nextjs/src/common/devErrorSymbolicationEventProcessor.ts index 3b02d92d80fb..c238e13efdf4 100644 --- a/packages/nextjs/src/common/devErrorSymbolicationEventProcessor.ts +++ b/packages/nextjs/src/common/devErrorSymbolicationEventProcessor.ts @@ -73,6 +73,7 @@ export async function devErrorSymbolicationEventProcessor(event: Event, hint: Ev // Due to changes across Next.js versions, there are a million things that can go wrong here so we just try-catch the // entire event processor. Symbolicated stack traces are just a nice to have. try { + // oxlint-disable-next-line typescript/prefer-optional-chain if (hint.originalException && hint.originalException instanceof Error && hint.originalException.stack) { const frames = stackTraceParser.parse(hint.originalException.stack); const nextJsVersion = globalWithInjectedValues._sentryNextJsVersion; diff --git a/packages/node-core/src/integrations/local-variables/local-variables-sync.ts b/packages/node-core/src/integrations/local-variables/local-variables-sync.ts index b2af37b0c7fb..66e78dd123fe 100644 --- a/packages/node-core/src/integrations/local-variables/local-variables-sync.ts +++ b/packages/node-core/src/integrations/local-variables/local-variables-sync.ts @@ -205,6 +205,7 @@ class AsyncSession implements DebugSession { private _unrollOther(prop: Runtime.PropertyDescriptor, vars: Variables, next: (vars: Variables) => void): void { if (prop.value) { if ('value' in prop.value) { + // oxlint-disable-next-line typescript/prefer-optional-chain if (prop.value.value === undefined || prop.value.value === null) { vars[prop.name] = `<${prop.value.value}>`; } else { diff --git a/packages/node-core/src/integrations/local-variables/worker.ts b/packages/node-core/src/integrations/local-variables/worker.ts index 304c7d527ef7..c0e7b5f07bde 100644 --- a/packages/node-core/src/integrations/local-variables/worker.ts +++ b/packages/node-core/src/integrations/local-variables/worker.ts @@ -46,6 +46,7 @@ function unrollOther(prop: Runtime.PropertyDescriptor, vars: Variables): void { } if ('value' in prop.value) { + // oxlint-disable-next-line typescript/prefer-optional-chain if (prop.value.value === undefined || prop.value.value === null) { vars[prop.name] = `<${prop.value.value}>`; } else { diff --git a/packages/node-core/src/utils/detection.ts b/packages/node-core/src/utils/detection.ts index f7ae9a792c27..435f3b2a6686 100644 --- a/packages/node-core/src/utils/detection.ts +++ b/packages/node-core/src/utils/detection.ts @@ -4,6 +4,7 @@ import { NODE_MAJOR, NODE_MINOR } from '../nodeVersion'; /** Detect CommonJS. */ export function isCjs(): boolean { try { + // oxlint-disable-next-line typescript/prefer-optional-chain return typeof module !== 'undefined' && typeof module.exports !== 'undefined'; } catch { return false; diff --git a/packages/react/src/hoist-non-react-statics.ts b/packages/react/src/hoist-non-react-statics.ts index 792e05584e38..2e150c4350d1 100644 --- a/packages/react/src/hoist-non-react-statics.ts +++ b/packages/react/src/hoist-non-react-statics.ts @@ -146,7 +146,7 @@ export function hoistNonReactStatics< // Use key directly - String(key) throws for Symbols if minified to '' + key (#18966) if ( !KNOWN_STATICS[key as keyof typeof KNOWN_STATICS] && - !(excludelist && excludelist[key as keyof C]) && + !excludelist?.[key as keyof C] && !sourceStatics?.[key as string] && !targetStatics?.[key as string] && !getOwnPropertyDescriptor(targetComponent, key) // Don't overwrite existing properties diff --git a/packages/react/src/reactrouter-compat-utils/instrumentation.tsx b/packages/react/src/reactrouter-compat-utils/instrumentation.tsx index e73438312676..54c344956948 100644 --- a/packages/react/src/reactrouter-compat-utils/instrumentation.tsx +++ b/packages/react/src/reactrouter-compat-utils/instrumentation.tsx @@ -614,8 +614,8 @@ export function createV6CompatibleWrapCreateMemoryRouter< const initialEntries = opts?.initialEntries; const initialIndex = opts?.initialIndex; - const hasOnlyOneInitialEntry = initialEntries && initialEntries.length === 1; - const hasIndexedEntry = initialIndex !== undefined && initialEntries && initialEntries[initialIndex]; + const hasOnlyOneInitialEntry = initialEntries?.length === 1; + const hasIndexedEntry = initialIndex !== undefined && initialEntries?.[initialIndex]; initialEntry = hasOnlyOneInitialEntry ? initialEntries[0] diff --git a/packages/react/src/reactrouter-compat-utils/route-manifest.ts b/packages/react/src/reactrouter-compat-utils/route-manifest.ts index 6160cad657c3..bdc49f76705e 100644 --- a/packages/react/src/reactrouter-compat-utils/route-manifest.ts +++ b/packages/react/src/reactrouter-compat-utils/route-manifest.ts @@ -36,7 +36,7 @@ const SORTED_MANIFEST_CACHE = new WeakMap(); * Optionally strips a basename prefix before matching. */ export function matchRouteManifest(pathname: string, manifest: string[], basename?: string): string | null { - if (!pathname || !manifest || !manifest.length) { + if (!pathname || !manifest?.length) { return null; } diff --git a/packages/remix/src/client/performance.tsx b/packages/remix/src/client/performance.tsx index 213f4eb43176..b3cde64d72de 100644 --- a/packages/remix/src/client/performance.tsx +++ b/packages/remix/src/client/performance.tsx @@ -169,7 +169,7 @@ export function withSentry

, R extends React.Co const matches = _useMatches(); _useEffect(() => { - const lastMatch = matches && matches[matches.length - 1]; + const lastMatch = matches?.[matches.length - 1]; if (lastMatch) { const { name, source } = getTransactionNameAndSource(location.pathname, lastMatch.id); diff --git a/packages/replay-internal/src/coreHandlers/handleAfterSendEvent.ts b/packages/replay-internal/src/coreHandlers/handleAfterSendEvent.ts index 4df1b62532ac..ae0f6ad86be4 100644 --- a/packages/replay-internal/src/coreHandlers/handleAfterSendEvent.ts +++ b/packages/replay-internal/src/coreHandlers/handleAfterSendEvent.ts @@ -57,7 +57,7 @@ function handleErrorEvent(replay: ReplayContainer, event: ErrorEvent): void { // If error event is tagged with replay id it means it was sampled (when in buffer mode) // Need to be very careful that this does not cause an infinite loop - if (replay.recordingMode !== 'buffer' || !event.tags || !event.tags.replayId) { + if (replay.recordingMode !== 'buffer' || !event.tags?.replayId) { return; } diff --git a/packages/replay-internal/src/replay.ts b/packages/replay-internal/src/replay.ts index 10dba8758d8a..cab408ca9d5d 100644 --- a/packages/replay-internal/src/replay.ts +++ b/packages/replay-internal/src/replay.ts @@ -748,8 +748,7 @@ export class ReplayContainer implements ReplayContainerInterface { if ( this._lastActivity && isExpired(this._lastActivity, this.timeouts.sessionIdlePause) && - this.session && - this.session.sampled === 'session' + this.session?.sampled === 'session' ) { // Pause recording only for session-based replays. Otherwise, resuming // will create a new replay and will conflict with users who only choose diff --git a/packages/replay-internal/src/util/handleRecordingEmit.ts b/packages/replay-internal/src/util/handleRecordingEmit.ts index aeb49f0cd259..215f94daa1db 100644 --- a/packages/replay-internal/src/util/handleRecordingEmit.ts +++ b/packages/replay-internal/src/util/handleRecordingEmit.ts @@ -146,7 +146,7 @@ export function createOptionsEvent(replay: ReplayContainer): ReplayOptionFrameEv */ function addSettingsEvent(replay: ReplayContainer, isCheckout?: boolean): void { // Only need to add this event when sending the first segment - if (!isCheckout || !replay.session || replay.session.segmentId !== 0) { + if (!isCheckout || replay.session?.segmentId !== 0) { return; } diff --git a/packages/sveltekit/src/server-common/handle.ts b/packages/sveltekit/src/server-common/handle.ts index 26872a0f6f24..761445739305 100644 --- a/packages/sveltekit/src/server-common/handle.ts +++ b/packages/sveltekit/src/server-common/handle.ts @@ -254,6 +254,7 @@ export function sentryHandle(handlerOptions?: SentryHandleOptions): Handle { // Escape hatch to suppress request isolation and trace continuation (see initCloudflareSentryHandle) const skipIsolation = + // oxlint-disable-next-line typescript/prefer-optional-chain '_sentrySkipRequestIsolation' in backwardsForwardsCompatibleEvent.locals && backwardsForwardsCompatibleEvent.locals._sentrySkipRequestIsolation; From 03031d0a5c4a5a44f977f7c959b9a1194967c20f Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Thu, 19 Feb 2026 11:57:28 -0500 Subject: [PATCH 05/22] chore: enable no-unsafe-member-access --- .oxlintrc.json | 7 ++----- packages/astro/src/server/middleware.ts | 3 ++- packages/nuxt/src/runtime/utils.ts | 1 + 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.oxlintrc.json b/.oxlintrc.json index 484b222da30b..1d05d5b782dc 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -63,14 +63,11 @@ "typescript/prefer-for-of": "error", "typescript/no-floating-promises": ["error", { "ignoreVoid": true }], "typescript/no-dynamic-delete": "error", - // "typescript/no-unsafe-member-access": "error", + "typescript/no-unsafe-member-access": "error", "typescript/unbound-method": "error", "typescript/no-explicit-any": "error", "typescript/no-empty-function": "off", - "typescript/prefer-optional-chain": ["error"], - - // === FIXME: Rules to turn back as error === - "typescript/no-unsafe-member-access": "warn" + "typescript/prefer-optional-chain": ["error"] } }, { diff --git a/packages/astro/src/server/middleware.ts b/packages/astro/src/server/middleware.ts index a12c25ff6045..b42be72ae846 100644 --- a/packages/astro/src/server/middleware.ts +++ b/packages/astro/src/server/middleware.ts @@ -423,9 +423,10 @@ function getParametrizedRoute( // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access const routesFromManifest = ctx?.[Symbol.for('context.routes')]?.manifest?.routes; - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + // oxlint-disable-next-line typescript/no-unsafe-member-access const matchedRouteSegmentsFromManifest = routesFromManifest?.find( (route: { routeData?: { route?: string } }) => route?.routeData?.route === rawRoutePattern, + // oxlint-disable-next-line typescript/no-unsafe-member-access )?.routeData?.segments; return ( diff --git a/packages/nuxt/src/runtime/utils.ts b/packages/nuxt/src/runtime/utils.ts index ce8069c58cdb..2c3526b951c9 100644 --- a/packages/nuxt/src/runtime/utils.ts +++ b/packages/nuxt/src/runtime/utils.ts @@ -72,6 +72,7 @@ export function reportNuxtError(options: { const sentryOptions = sentryClient ? (sentryClient.getOptions() as ClientOptions & VueOptions) : null; // `attachProps` is enabled by default and props should only not be attached if explicitly disabled (see DEFAULT_CONFIG in `vueIntegration`). + // oxlint-disable-next-line typescript/no-unsafe-member-access if (sentryOptions?.attachProps && instance.$props !== false) { metadata.propsData = instance.$props; } From 41b258d4ea5f6ac965da3136d845168d71562c2f Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Mon, 9 Mar 2026 10:03:07 -0400 Subject: [PATCH 06/22] chore: remove unused imports --- dev-packages/rollup-utils/plugins/npmPlugins.mjs | 3 --- 1 file changed, 3 deletions(-) diff --git a/dev-packages/rollup-utils/plugins/npmPlugins.mjs b/dev-packages/rollup-utils/plugins/npmPlugins.mjs index 3cb9ca7d50f9..221a4a34f8c4 100644 --- a/dev-packages/rollup-utils/plugins/npmPlugins.mjs +++ b/dev-packages/rollup-utils/plugins/npmPlugins.mjs @@ -7,9 +7,6 @@ * Sucrase plugin docs: https://github.com/rollup/plugins/tree/master/packages/sucrase */ -import * as fs from 'fs'; -import * as path from 'path'; - import json from '@rollup/plugin-json'; import replace from '@rollup/plugin-replace'; import cleanup from 'rollup-plugin-cleanup'; From ab2b8d225d3d9da5ecb3c778af516db672d1cd55 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Mon, 9 Mar 2026 10:03:20 -0400 Subject: [PATCH 07/22] ref: deleted unused debugger.info method --- packages/core/src/utils/debug-logger.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/core/src/utils/debug-logger.ts b/packages/core/src/utils/debug-logger.ts index bbc524729674..6f52020986a4 100644 --- a/packages/core/src/utils/debug-logger.ts +++ b/packages/core/src/utils/debug-logger.ts @@ -85,10 +85,6 @@ function log(...args: Parameters): void { _maybeLog('log', ...args); } -function info(...args: Parameters): void { - _maybeLog('info', ...args); -} - function warn(...args: Parameters): void { _maybeLog('warn', ...args); } From 355ad20fb858c846da23090448694fcba4e997f8 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Mon, 9 Mar 2026 10:24:29 -0400 Subject: [PATCH 08/22] lint: remove redundant undefineds --- packages/astro/src/index.types.ts | 4 ++-- packages/core/src/client.ts | 6 +++--- packages/core/src/tracing/sentryNonRecordingSpan.ts | 2 +- packages/core/src/tracing/sentrySpan.ts | 2 +- packages/core/src/utils/hasSpansEnabled.ts | 2 +- packages/core/src/utils/url.ts | 4 ++-- packages/deno/src/client.ts | 2 +- .../integrations/local-variables/local-variables-sync.ts | 2 +- packages/node-core/src/light/client.ts | 2 +- packages/node-core/src/sdk/client.ts | 2 +- packages/remix/src/utils/utils.ts | 2 +- packages/solidstart/src/index.types.ts | 4 ++-- packages/sveltekit/src/index.types.ts | 4 ++-- 13 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/astro/src/index.types.ts b/packages/astro/src/index.types.ts index 2e51ab1b0f1e..3958d4bc0c59 100644 --- a/packages/astro/src/index.types.ts +++ b/packages/astro/src/index.types.ts @@ -24,8 +24,8 @@ export declare const contextLinesIntegration: typeof clientSdk.contextLinesInteg export declare const getDefaultIntegrations: (options: Options) => Integration[]; export declare const defaultStackParser: StackParser; -export declare function close(timeout?: number | undefined): PromiseLike; -export declare function flush(timeout?: number | undefined): PromiseLike; +export declare function close(timeout?: number): PromiseLike; +export declare function flush(timeout?: number): PromiseLike; export declare const Span: clientSdk.Span; diff --git a/packages/core/src/client.ts b/packages/core/src/client.ts index 5af07635947e..644b851e42c3 100644 --- a/packages/core/src/client.ts +++ b/packages/core/src/client.ts @@ -637,7 +637,7 @@ export abstract class Client { * Receives an Event & EventHint as arguments. * @returns {() => void} A function that, when executed, removes the registered callback. */ - public on(hook: 'beforeSendEvent', callback: (event: Event, hint?: EventHint | undefined) => void): () => void; + public on(hook: 'beforeSendEvent', callback: (event: Event, hint?: EventHint) => void): () => void; /** * Register a callback for before sending a session or session aggregrates.. @@ -652,7 +652,7 @@ export abstract class Client { * Receives an Event & EventHint as arguments. * @returns {() => void} A function that, when executed, removes the registered callback. */ - public on(hook: 'preprocessEvent', callback: (event: Event, hint?: EventHint | undefined) => void): () => void; + public on(hook: 'preprocessEvent', callback: (event: Event, hint?: EventHint) => void): () => void; /** * Register a callback for postprocessing an event, @@ -660,7 +660,7 @@ export abstract class Client { * Receives an Event & EventHint as arguments. * @returns {() => void} A function that, when executed, removes the registered callback. */ - public on(hook: 'postprocessEvent', callback: (event: Event, hint?: EventHint | undefined) => void): () => void; + public on(hook: 'postprocessEvent', callback: (event: Event, hint?: EventHint) => void): () => void; /** * Register a callback for when an event has been sent. diff --git a/packages/core/src/tracing/sentryNonRecordingSpan.ts b/packages/core/src/tracing/sentryNonRecordingSpan.ts index 2f65e0eb8c08..7fbd7623215f 100644 --- a/packages/core/src/tracing/sentryNonRecordingSpan.ts +++ b/packages/core/src/tracing/sentryNonRecordingSpan.ts @@ -85,7 +85,7 @@ export class SentryNonRecordingSpan implements Span { * @hidden * @internal */ - public recordException(_exception: unknown, _time?: number | undefined): void { + public recordException(_exception: unknown, _time?: number): void { // noop } } diff --git a/packages/core/src/tracing/sentrySpan.ts b/packages/core/src/tracing/sentrySpan.ts index 9bd98b9741c6..f4ebbe00d104 100644 --- a/packages/core/src/tracing/sentrySpan.ts +++ b/packages/core/src/tracing/sentrySpan.ts @@ -138,7 +138,7 @@ export class SentrySpan implements Span { * @hidden * @internal */ - public recordException(_exception: unknown, _time?: number | undefined): void { + public recordException(_exception: unknown, _time?: number): void { // noop } diff --git a/packages/core/src/utils/hasSpansEnabled.ts b/packages/core/src/utils/hasSpansEnabled.ts index cfa447fd86bd..2e72de003718 100644 --- a/packages/core/src/utils/hasSpansEnabled.ts +++ b/packages/core/src/utils/hasSpansEnabled.ts @@ -21,7 +21,7 @@ declare const __SENTRY_TRACING__: boolean | undefined; * If this option is not provided, the function will use the current client's options. */ export function hasSpansEnabled( - maybeOptions?: Pick | undefined, + maybeOptions?: Pick, ): boolean { if (typeof __SENTRY_TRACING__ === 'boolean' && !__SENTRY_TRACING__) { return false; diff --git a/packages/core/src/utils/url.ts b/packages/core/src/utils/url.ts index bf0c17dbc278..9514b3bee4be 100644 --- a/packages/core/src/utils/url.ts +++ b/packages/core/src/utils/url.ts @@ -16,7 +16,7 @@ type PartialURL = { }; interface URLwithCanParse extends URL { - canParse: (url: string, base?: string | URL | undefined) => boolean; + canParse: (url: string, base?: string | URL) => boolean; } // A subset of the URL object that is valid for relative URLs @@ -60,7 +60,7 @@ export function isURLObjectRelative(url: URLObject): url is RelativeURL { * @param url - The URL to parse * @returns The parsed URL object or undefined if the URL is invalid */ -export function parseStringToURLObject(url: string, urlBase?: string | URL | undefined): URLObject | undefined { +export function parseStringToURLObject(url: string, urlBase?: string | URL): URLObject | undefined { const isRelative = url.indexOf('://') <= 0 && url.indexOf('//') !== 0; const base = urlBase ?? (isRelative ? DEFAULT_BASE_URL : undefined); try { diff --git a/packages/deno/src/client.ts b/packages/deno/src/client.ts index 36886c8d5a5e..b5de02f792ee 100644 --- a/packages/deno/src/client.ts +++ b/packages/deno/src/client.ts @@ -69,7 +69,7 @@ export class DenoClient extends ServerRuntimeClient { /** @inheritDoc */ // @ts-expect-error - PromiseLike is a subset of Promise - public async close(timeout?: number | undefined): PromiseLike { + public async close(timeout?: number): PromiseLike { if (this._logOnExitFlushListener) { globalThis.removeEventListener('unload', this._logOnExitFlushListener); } diff --git a/packages/node-core/src/integrations/local-variables/local-variables-sync.ts b/packages/node-core/src/integrations/local-variables/local-variables-sync.ts index 66e78dd123fe..406391f658d2 100644 --- a/packages/node-core/src/integrations/local-variables/local-variables-sync.ts +++ b/packages/node-core/src/integrations/local-variables/local-variables-sync.ts @@ -100,7 +100,7 @@ class AsyncSession implements DebugSession { // } - public static async create(orDefault?: DebugSession | undefined): Promise { + public static async create(orDefault?: DebugSession): Promise { if (orDefault) { return orDefault; } diff --git a/packages/node-core/src/light/client.ts b/packages/node-core/src/light/client.ts index 074f5231009e..237e38019799 100644 --- a/packages/node-core/src/light/client.ts +++ b/packages/node-core/src/light/client.ts @@ -62,7 +62,7 @@ export class LightNodeClient extends ServerRuntimeClient { /** @inheritDoc */ // @ts-expect-error - PromiseLike is a subset of Promise - public async close(timeout?: number | undefined): PromiseLike { + public async close(timeout?: number): PromiseLike { if (this._clientReportInterval) { clearInterval(this._clientReportInterval); } diff --git a/packages/node-core/src/sdk/client.ts b/packages/node-core/src/sdk/client.ts index 80a233aa3954..bc706d2fe888 100644 --- a/packages/node-core/src/sdk/client.ts +++ b/packages/node-core/src/sdk/client.ts @@ -101,7 +101,7 @@ export class NodeClient extends ServerRuntimeClient { /** @inheritDoc */ // @ts-expect-error - PromiseLike is a subset of Promise - public async close(timeout?: number | undefined): PromiseLike { + public async close(timeout?: number): PromiseLike { if (this._clientReportInterval) { clearInterval(this._clientReportInterval); } diff --git a/packages/remix/src/utils/utils.ts b/packages/remix/src/utils/utils.ts index 83dda0b816a3..c179bc43f61f 100644 --- a/packages/remix/src/utils/utils.ts +++ b/packages/remix/src/utils/utils.ts @@ -13,7 +13,7 @@ type ServerRouteManifest = ServerBuild['routes']; export async function storeFormDataKeys( args: LoaderFunctionArgs | ActionFunctionArgs, span: Span, - formDataKeys?: Record | undefined, + formDataKeys?: Record, ): Promise { try { // We clone the request for Remix be able to read the FormData later. diff --git a/packages/solidstart/src/index.types.ts b/packages/solidstart/src/index.types.ts index da45898b3915..4c5ff491c740 100644 --- a/packages/solidstart/src/index.types.ts +++ b/packages/solidstart/src/index.types.ts @@ -22,8 +22,8 @@ export declare const contextLinesIntegration: typeof clientSdk.contextLinesInteg export declare const getDefaultIntegrations: (options: Options) => Integration[]; export declare const defaultStackParser: StackParser; -export declare function close(timeout?: number | undefined): PromiseLike; -export declare function flush(timeout?: number | undefined): PromiseLike; +export declare function close(timeout?: number): PromiseLike; +export declare function flush(timeout?: number): PromiseLike; export declare function lastEventId(): string | undefined; export declare const logger: typeof clientSdk.logger | typeof serverSdk.logger; diff --git a/packages/sveltekit/src/index.types.ts b/packages/sveltekit/src/index.types.ts index f6bdfef640c7..d46e88e720ed 100644 --- a/packages/sveltekit/src/index.types.ts +++ b/packages/sveltekit/src/index.types.ts @@ -54,8 +54,8 @@ export declare const vercelAIIntegration: typeof serverSdk.vercelAIIntegration; export declare const getDefaultIntegrations: (options: Options) => Integration[]; export declare const defaultStackParser: StackParser; -export declare function close(timeout?: number | undefined): PromiseLike; -export declare function flush(timeout?: number | undefined): PromiseLike; +export declare function close(timeout?: number): PromiseLike; +export declare function flush(timeout?: number): PromiseLike; export declare function lastEventId(): string | undefined; export declare function trackComponent(options: clientSdk.TrackingOptions): ReturnType; From 7cf7e2cf58c276e92f9675c4ae8a7a001c4b0293 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Mon, 9 Mar 2026 10:24:40 -0400 Subject: [PATCH 09/22] chore: disable several rules --- .oxlintrc.json | 10 ++++++++-- dev-packages/.oxlintrc.json | 4 +++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.oxlintrc.json b/.oxlintrc.json index 1d05d5b782dc..91c2b79428b0 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -67,7 +67,11 @@ "typescript/unbound-method": "error", "typescript/no-explicit-any": "error", "typescript/no-empty-function": "off", - "typescript/prefer-optional-chain": ["error"] + "typescript/prefer-optional-chain": ["error"], + "typescript/no-redundant-type-constituents": "off", + "typescript/restrict-template-expressions": "off", + "typescript/await-thenable": "off", + "typescript/no-base-to-string": "warn" } }, { @@ -108,7 +112,9 @@ "typescript/unbound-method": "off", "max-lines": "off", "complexity": "off", - "typescript/prefer-optional-chain": "off" + "typescript/prefer-optional-chain": "off", + "typescript/no-misused-spread": "off", + "typescript/require-array-sort-compare": "off" } }, { diff --git a/dev-packages/.oxlintrc.json b/dev-packages/.oxlintrc.json index f44c8f60b0db..1051f1732cea 100644 --- a/dev-packages/.oxlintrc.json +++ b/dev-packages/.oxlintrc.json @@ -4,6 +4,8 @@ "rules": { "typescript/no-explicit-any": "off", "max-lines": "off", - "no-unused-expressions": "off" + "no-unused-expressions": "off", + "typescript/require-array-sort-compare": "off", + "typescript/no-misused-spread": "off" } } From d840f01286043ba40084a249aa17c0b2ea2d5852 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Mon, 9 Mar 2026 10:30:53 -0400 Subject: [PATCH 10/22] lint: fix unused vars by prefixing _ --- .oxlintrc.json | 2 ++ dev-packages/browser-integration-tests/utils/replayHelpers.ts | 4 ++-- .../suites/tracing/google-genai/scenario.mjs | 2 +- dev-packages/node-overhead-gh-action/index.mjs | 2 +- dev-packages/size-limit-gh-action/index.mjs | 2 +- .../browser-utils/src/metrics/web-vitals/lib/initUnique.ts | 2 +- packages/browser/src/profiling/utils.ts | 2 +- packages/bun/scripts/install-bun.js | 2 +- packages/cloudflare/src/request.ts | 2 +- packages/cloudflare/test/workflow.test.ts | 2 +- packages/core/src/integrations/mcp-server/handlers.ts | 2 +- packages/core/src/utils/exports.ts | 4 ++-- packages/core/test/lib/transports/base.test.ts | 4 ++-- packages/deno/src/utils/streaming.ts | 2 +- .../google-cloud-serverless/test/gcpfunction/http.test.ts | 2 +- packages/node-core/src/transports/http.ts | 2 +- packages/node-core/src/utils/captureRequestBody.ts | 2 +- .../src/integrations/tracing/anthropic-ai/instrumentation.ts | 4 ++-- .../node/src/integrations/tracing/openai/instrumentation.ts | 4 ++-- packages/nuxt/src/runtime/plugins/storage.server.ts | 2 +- packages/react/src/hoist-non-react-statics.ts | 2 +- packages/remix/src/client/remixRouteParameterization.ts | 2 +- packages/sveltekit/test/server-common/handle.test.ts | 2 +- 23 files changed, 29 insertions(+), 27 deletions(-) diff --git a/.oxlintrc.json b/.oxlintrc.json index 91c2b79428b0..7ee230fc983e 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -9,6 +9,8 @@ ], "categories": {}, "rules": { + "no-unused-vars": ["warn", { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_", "caughtErrorsIgnorePattern": "^_" }], + // === Base rules from eslint-config-sdk/base.js === "no-console": "error", "no-alert": "error", diff --git a/dev-packages/browser-integration-tests/utils/replayHelpers.ts b/dev-packages/browser-integration-tests/utils/replayHelpers.ts index 36af7740047e..23ab2dab6400 100644 --- a/dev-packages/browser-integration-tests/utils/replayHelpers.ts +++ b/dev-packages/browser-integration-tests/utils/replayHelpers.ts @@ -364,7 +364,7 @@ export function replayEnvelopeIsCompressed(resOrReq: Request | Response): boolea const lines: boolean[] = envelopeString.split('\n').map(line => { try { JSON.parse(line); - } catch (error) { + } catch (_error) { // If we fail to parse a line, we _might_ have found a compressed payload, // so let's check if this is actually the case. // This is quite hacky but we can't go through `line` because the prior operations @@ -394,7 +394,7 @@ export const replayEnvelopeParser = (request: Request | null): unknown[] => { const lines = envelopeString.split('\n').map(line => { try { return JSON.parse(line); - } catch (error) { + } catch (_error) { // If we fail to parse a line, we _might_ have found a compressed payload, // so let's check if this is actually the case. // This is quite hacky but we can't go through `line` because the prior operations diff --git a/dev-packages/node-integration-tests/suites/tracing/google-genai/scenario.mjs b/dev-packages/node-integration-tests/suites/tracing/google-genai/scenario.mjs index 40f8af031f5a..ea5a2b33b05a 100644 --- a/dev-packages/node-integration-tests/suites/tracing/google-genai/scenario.mjs +++ b/dev-packages/node-integration-tests/suites/tracing/google-genai/scenario.mjs @@ -102,7 +102,7 @@ async function run() { }, ], }); - } catch (error) { + } catch (_error) { // Expected error } }); diff --git a/dev-packages/node-overhead-gh-action/index.mjs b/dev-packages/node-overhead-gh-action/index.mjs index 0a0f02e41b9a..6e04a9f98850 100644 --- a/dev-packages/node-overhead-gh-action/index.mjs +++ b/dev-packages/node-overhead-gh-action/index.mjs @@ -157,7 +157,7 @@ async function run() { body, }); } - } catch (error) { + } catch (_error) { core.error( "Error updating comment. This can happen for PR's originating from a fork without write permissions.", ); diff --git a/dev-packages/size-limit-gh-action/index.mjs b/dev-packages/size-limit-gh-action/index.mjs index 3dac81a3f080..c40b4dfe0cb5 100644 --- a/dev-packages/size-limit-gh-action/index.mjs +++ b/dev-packages/size-limit-gh-action/index.mjs @@ -171,7 +171,7 @@ async function run() { body, }); } - } catch (error) { + } catch (_error) { core.error( "Error updating comment. This can happen for PR's originating from a fork without write permissions.", ); diff --git a/packages/browser-utils/src/metrics/web-vitals/lib/initUnique.ts b/packages/browser-utils/src/metrics/web-vitals/lib/initUnique.ts index ef3e721dc09e..5043dcaa62b6 100644 --- a/packages/browser-utils/src/metrics/web-vitals/lib/initUnique.ts +++ b/packages/browser-utils/src/metrics/web-vitals/lib/initUnique.ts @@ -27,7 +27,7 @@ export function initUnique(identityObj: object, ClassObj: new () => T): T { instanceMap.set(identityObj, new ClassObj()); } return instanceMap.get(identityObj)! as T; - } catch (e) { + } catch (_e) { // --- START Sentry-custom code (try/catch wrapping) --- // Fix for cases where identityObj is not a valid key for WeakMap (sometimes a problem in Safari) // Just return a new instance without caching it in instanceMap diff --git a/packages/browser/src/profiling/utils.ts b/packages/browser/src/profiling/utils.ts index dceb5e45a691..f0d067c841d8 100644 --- a/packages/browser/src/profiling/utils.ts +++ b/packages/browser/src/profiling/utils.ts @@ -614,7 +614,7 @@ export function startJSSelfProfile(): JSSelfProfiler | undefined { // as we risk breaking the user's application, so just disable profiling and log an error. try { return new JSProfilerConstructor({ sampleInterval: samplingIntervalMS, maxBufferSize: maxSamples }); - } catch (e) { + } catch (_e) { if (DEBUG_BUILD) { debug.log( "[Profiling] Failed to initialize the Profiling constructor, this is likely due to a missing 'Document-Policy': 'js-profiling' header.", diff --git a/packages/bun/scripts/install-bun.js b/packages/bun/scripts/install-bun.js index e2221e549d3e..2c14afa5d273 100644 --- a/packages/bun/scripts/install-bun.js +++ b/packages/bun/scripts/install-bun.js @@ -10,7 +10,7 @@ const https = require('https'); const installScriptUrl = 'https://bun.sh/install'; // Check if bun is installed -exec('bun --version', (error, version) => { +exec('bun --version', (error, _version) => { if (error) { console.error('bun is not installed. Installing...'); installLatestBun(); diff --git a/packages/cloudflare/src/request.ts b/packages/cloudflare/src/request.ts index 5ad215aab428..9d8d63eab8c1 100644 --- a/packages/cloudflare/src/request.ts +++ b/packages/cloudflare/src/request.ts @@ -162,7 +162,7 @@ export function wrapRequestHandler( statusText: res.statusText, headers: res.headers, }); - } catch (e) { + } catch (_e) { // tee() failed (e.g stream already locked) - fall back to non-streaming handling span.end(); waitUntil?.(flushAndDispose(client)); diff --git a/packages/cloudflare/test/workflow.test.ts b/packages/cloudflare/test/workflow.test.ts index fa922d7233e0..f42331c1095a 100644 --- a/packages/cloudflare/test/workflow.test.ts +++ b/packages/cloudflare/test/workflow.test.ts @@ -26,7 +26,7 @@ const mockStep: WorkflowStep = { } else { return await (maybeCallback ? maybeCallback() : Promise.resolve()); } - } catch (error) { + } catch (_error) { await new Promise(resolve => setTimeout(resolve, 1000)); } } diff --git a/packages/core/src/integrations/mcp-server/handlers.ts b/packages/core/src/integrations/mcp-server/handlers.ts index 9816d607b7c1..dd8e0296a95e 100644 --- a/packages/core/src/integrations/mcp-server/handlers.ts +++ b/packages/core/src/integrations/mcp-server/handlers.ts @@ -121,7 +121,7 @@ function captureHandlerError(error: Error, methodName: keyof MCPServerInstance, extraData.prompt_name = handlerName; captureError(error, 'prompt_execution', extraData); } - } catch (captureErr) { + } catch (_captureErr) { // noop } } diff --git a/packages/core/src/utils/exports.ts b/packages/core/src/utils/exports.ts index 588e758e88f9..72bdb4eb1623 100644 --- a/packages/core/src/utils/exports.ts +++ b/packages/core/src/utils/exports.ts @@ -21,7 +21,7 @@ export function replaceExports( // Replace the named export - handle read-only properties try { exports[exportName] = wrappedConstructor; - } catch (error) { + } catch (_error) { // If direct assignment fails, override the property descriptor Object.defineProperty(exports, exportName, { value: wrappedConstructor, @@ -35,7 +35,7 @@ export function replaceExports( if (exports.default === original) { try { exports.default = wrappedConstructor; - } catch (error) { + } catch (_error) { Object.defineProperty(exports, 'default', { value: wrappedConstructor, writable: true, diff --git a/packages/core/test/lib/transports/base.test.ts b/packages/core/test/lib/transports/base.test.ts index 5908e4f1877e..f1a747a64917 100644 --- a/packages/core/test/lib/transports/base.test.ts +++ b/packages/core/test/lib/transports/base.test.ts @@ -339,7 +339,7 @@ describe('createTransport', () => { try { await transport.send(CLIENT_REPORT_ENVELOPE); - } catch (e) { + } catch (_e) { // Expected to throw } @@ -383,7 +383,7 @@ describe('createTransport', () => { try { await transport.send(ERROR_ENVELOPE); - } catch (e) { + } catch (_e) { // Expected to throw } diff --git a/packages/deno/src/utils/streaming.ts b/packages/deno/src/utils/streaming.ts index 4f6f4654af68..045a104c5e93 100644 --- a/packages/deno/src/utils/streaming.ts +++ b/packages/deno/src/utils/streaming.ts @@ -66,7 +66,7 @@ export async function streamResponse(span: Span, res: Response): Promise { try { fn(req, res); - } catch (error) { + } catch (_error) { res.end(); } }); diff --git a/packages/node-core/src/transports/http.ts b/packages/node-core/src/transports/http.ts index 7b2cea994a17..25e5d5f51125 100644 --- a/packages/node-core/src/transports/http.ts +++ b/packages/node-core/src/transports/http.ts @@ -48,7 +48,7 @@ export function makeNodeTransport(options: NodeTransportOptions): Transport { try { urlSegments = new URL(options.url); - } catch (e) { + } catch (_e) { consoleSandbox(() => { // eslint-disable-next-line no-console console.warn( diff --git a/packages/node-core/src/utils/captureRequestBody.ts b/packages/node-core/src/utils/captureRequestBody.ts index 3382409e0991..023209223f82 100644 --- a/packages/node-core/src/utils/captureRequestBody.ts +++ b/packages/node-core/src/utils/captureRequestBody.ts @@ -60,7 +60,7 @@ export function patchRequestToCaptureBody( `Dropping request body chunk because maximum body length of ${maxBodySize}b is exceeded.`, ); } - } catch (err) { + } catch (_err) { DEBUG_BUILD && debug.error(integrationName, 'Encountered error while storing body chunk.'); } diff --git a/packages/node/src/integrations/tracing/anthropic-ai/instrumentation.ts b/packages/node/src/integrations/tracing/anthropic-ai/instrumentation.ts index 4fc96aa5ea92..5adadb577f80 100644 --- a/packages/node/src/integrations/tracing/anthropic-ai/instrumentation.ts +++ b/packages/node/src/integrations/tracing/anthropic-ai/instrumentation.ts @@ -89,7 +89,7 @@ export class SentryAnthropicAiInstrumentation extends InstrumentationBase { it('send errors to Sentry', async () => { try { await sentryHandle()({ event: mockEvent(), resolve: resolve(type, isError) }); - } catch (e) { + } catch (_e) { expect(mockCaptureException).toBeCalledTimes(1); expect(mockCaptureException).toBeCalledWith(expect.any(Error), { mechanism: { handled: false, type: 'auto.function.sveltekit.handle' }, From 74d86ff620ca6f4f3917b1c4aac3b5e9fb253aac Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Mon, 9 Mar 2026 10:39:04 -0400 Subject: [PATCH 11/22] lint: remove jest rules since we use vitest --- .oxlintrc.json | 10 +++++++--- dev-packages/.oxlintrc.json | 3 ++- packages/core/test/lib/utils/object.test.ts | 1 + packages/node/src/integrations/tracing/graphql.ts | 1 + .../opentelemetry/src/utils/parseSpanDescription.ts | 1 + packages/replay-worker/test/unit/Compressor.test.ts | 2 +- 6 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.oxlintrc.json b/.oxlintrc.json index 7ee230fc983e..8591ee1bf062 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -1,6 +1,6 @@ { "$schema": "./node_modules/oxlint/configuration_schema.json", - "plugins": ["typescript", "import", "jsdoc", "jest", "vitest"], + "plugins": ["typescript", "import", "jsdoc", "vitest"], "jsPlugins": [ { "name": "sdk", @@ -9,7 +9,10 @@ ], "categories": {}, "rules": { - "no-unused-vars": ["warn", { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_", "caughtErrorsIgnorePattern": "^_" }], + "no-unused-vars": [ + "warn", + { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_", "caughtErrorsIgnorePattern": "^_" } + ], // === Base rules from eslint-config-sdk/base.js === "no-console": "error", @@ -116,7 +119,8 @@ "complexity": "off", "typescript/prefer-optional-chain": "off", "typescript/no-misused-spread": "off", - "typescript/require-array-sort-compare": "off" + "typescript/require-array-sort-compare": "off", + "typescript/no-base-to-string": "off" } }, { diff --git a/dev-packages/.oxlintrc.json b/dev-packages/.oxlintrc.json index 1051f1732cea..d60b62bef618 100644 --- a/dev-packages/.oxlintrc.json +++ b/dev-packages/.oxlintrc.json @@ -6,6 +6,7 @@ "max-lines": "off", "no-unused-expressions": "off", "typescript/require-array-sort-compare": "off", - "typescript/no-misused-spread": "off" + "typescript/no-misused-spread": "off", + "typescript/no-base-to-string": "off" } } diff --git a/packages/core/test/lib/utils/object.test.ts b/packages/core/test/lib/utils/object.test.ts index a4d2a4b56ea3..e34260edef50 100644 --- a/packages/core/test/lib/utils/object.test.ts +++ b/packages/core/test/lib/utils/object.test.ts @@ -343,6 +343,7 @@ describe('objectify()', () => { testOnlyIfNodeVersionAtLeast(10)('bigint', () => { // Hack to get around the fact that literal bigints cause a syntax error in older versions of Node, so the // assignment needs to not even be parsed as code in those versions + // oxlint-disable-next-line no-unassigned-vars let bigintPrimitive; eval('bigintPrimitive = 1231n;'); diff --git a/packages/node/src/integrations/tracing/graphql.ts b/packages/node/src/integrations/tracing/graphql.ts index db5760329e8d..9d8c66aef15f 100644 --- a/packages/node/src/integrations/tracing/graphql.ts +++ b/packages/node/src/integrations/tracing/graphql.ts @@ -136,6 +136,7 @@ function getOptionsWithDefaults(options?: GraphqlOptions): GraphqlOptions { // copy from packages/opentelemetry/utils function getGraphqlOperationNamesFromAttribute(attr: AttributeValue): string { if (Array.isArray(attr)) { + // oxlint-disable-next-line typescript/require-array-sort-compare const sorted = attr.slice().sort(); // Up to 5 items, we just add all of them diff --git a/packages/opentelemetry/src/utils/parseSpanDescription.ts b/packages/opentelemetry/src/utils/parseSpanDescription.ts index bb9c5f59acf7..fc0f92143516 100644 --- a/packages/opentelemetry/src/utils/parseSpanDescription.ts +++ b/packages/opentelemetry/src/utils/parseSpanDescription.ts @@ -220,6 +220,7 @@ export function descriptionForHttpMethod( function getGraphqlOperationNamesFromAttribute(attr: AttributeValue): string { if (Array.isArray(attr)) { + // oxlint-disable-next-line typescript/require-array-sort-compare const sorted = attr.slice().sort(); // Up to 5 items, we just add all of them diff --git a/packages/replay-worker/test/unit/Compressor.test.ts b/packages/replay-worker/test/unit/Compressor.test.ts index 74f01ef42168..2d4181c2ec28 100644 --- a/packages/replay-worker/test/unit/Compressor.test.ts +++ b/packages/replay-worker/test/unit/Compressor.test.ts @@ -30,7 +30,7 @@ describe('Compressor', () => { const compressor = new Compressor(); // @ts-expect-error ignoring type for test - expect(() => void compressor.addEvent(undefined)).toThrow(); + expect(() => compressor.addEvent(undefined)).toThrow(); const compressed = compressor.finish(); From b8f68dd210af1a07c653a4cc31a776538499c989 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Mon, 9 Mar 2026 10:42:44 -0400 Subject: [PATCH 12/22] lint: fix duplicate types --- packages/browser-utils/src/metrics/browserMetrics.ts | 1 - packages/core/src/types-hoist/polymorphics.ts | 9 +-------- packages/svelte/test/components/Dummy.svelte | 1 + 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/packages/browser-utils/src/metrics/browserMetrics.ts b/packages/browser-utils/src/metrics/browserMetrics.ts index 3c3dee074cb5..28d1f2bfaec8 100644 --- a/packages/browser-utils/src/metrics/browserMetrics.ts +++ b/packages/browser-utils/src/metrics/browserMetrics.ts @@ -573,7 +573,6 @@ type StartEventName = | 'loadEvent'; type EndEventName = - | 'connectEnd' | 'domainLookupStart' | 'domainLookupEnd' | 'unloadEventEnd' diff --git a/packages/core/src/types-hoist/polymorphics.ts b/packages/core/src/types-hoist/polymorphics.ts index 74ade60e2098..aaec637ba969 100644 --- a/packages/core/src/types-hoist/polymorphics.ts +++ b/packages/core/src/types-hoist/polymorphics.ts @@ -13,20 +13,13 @@ export interface PolymorphicEvent { } /** A `Request` type compatible with Node, Express, browser, etc., because everything is optional */ -export type PolymorphicRequest = BaseRequest & - BrowserRequest & - NodeRequest & - ExpressRequest & - KoaRequest & - NextjsRequest; +export type PolymorphicRequest = BaseRequest & NodeRequest & ExpressRequest & KoaRequest & NextjsRequest; type BaseRequest = { method?: string; url?: string; }; -type BrowserRequest = BaseRequest; - type NodeRequest = BaseRequest & { headers?: { [key: string]: string | string[] | undefined; diff --git a/packages/svelte/test/components/Dummy.svelte b/packages/svelte/test/components/Dummy.svelte index ef814473f6cf..12c066fc2c1b 100644 --- a/packages/svelte/test/components/Dummy.svelte +++ b/packages/svelte/test/components/Dummy.svelte @@ -3,6 +3,7 @@ import * as Sentry from '../../src/index'; // Pass options to trackComponent as props of this component + // oxlint-disable-next-line no-unassigned-vars export let options; Sentry.trackComponent(options); From 903df65883449755d112fcf5c5d8232ca65a1820 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Mon, 9 Mar 2026 10:46:23 -0400 Subject: [PATCH 13/22] fix: format --- packages/core/src/utils/hasSpansEnabled.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/core/src/utils/hasSpansEnabled.ts b/packages/core/src/utils/hasSpansEnabled.ts index 2e72de003718..cf01f7ffb5ef 100644 --- a/packages/core/src/utils/hasSpansEnabled.ts +++ b/packages/core/src/utils/hasSpansEnabled.ts @@ -20,9 +20,7 @@ declare const __SENTRY_TRACING__: boolean | undefined; * @param maybeOptions An SDK options object to be passed to this function. * If this option is not provided, the function will use the current client's options. */ -export function hasSpansEnabled( - maybeOptions?: Pick, -): boolean { +export function hasSpansEnabled(maybeOptions?: Pick): boolean { if (typeof __SENTRY_TRACING__ === 'boolean' && !__SENTRY_TRACING__) { return false; } From fe828c5dae6d635ef28da17f31bda6a9e5e1bfd2 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Mon, 9 Mar 2026 10:47:47 -0400 Subject: [PATCH 14/22] chore: revert nx change --- nx.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nx.json b/nx.json index 5cc18211d58b..7cd807e089fb 100644 --- a/nx.json +++ b/nx.json @@ -51,7 +51,7 @@ "inputs": ["default"], "dependsOn": ["^build:types", "build:types"], "outputs": [], - "cache": false + "cache": true }, "test:unit": { "dependsOn": ["build:types", "^build:types", "build:transpile", "^build:transpile"], From 1e954ab75fd35e0658aeb2ae53f6193e70f939d7 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Mon, 9 Mar 2026 16:46:31 -0400 Subject: [PATCH 15/22] lint: configure await-thenable as warn, disable in tests/dev-packages Most await-thenable violations are in tests or are false positives where code intentionally handles T | Promise uniformly. Keep as warn for production source to catch genuinely unnecessary awaits. Co-Authored-By: Claude Opus 4.6 --- .oxlintrc.json | 5 +++-- dev-packages/.oxlintrc.json | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.oxlintrc.json b/.oxlintrc.json index 8591ee1bf062..fc71599097f8 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -75,7 +75,7 @@ "typescript/prefer-optional-chain": ["error"], "typescript/no-redundant-type-constituents": "off", "typescript/restrict-template-expressions": "off", - "typescript/await-thenable": "off", + "typescript/await-thenable": "warn", "typescript/no-base-to-string": "warn" } }, @@ -120,7 +120,8 @@ "typescript/prefer-optional-chain": "off", "typescript/no-misused-spread": "off", "typescript/require-array-sort-compare": "off", - "typescript/no-base-to-string": "off" + "typescript/no-base-to-string": "off", + "typescript/await-thenable": "off" } }, { diff --git a/dev-packages/.oxlintrc.json b/dev-packages/.oxlintrc.json index d60b62bef618..72497867a535 100644 --- a/dev-packages/.oxlintrc.json +++ b/dev-packages/.oxlintrc.json @@ -7,6 +7,7 @@ "no-unused-expressions": "off", "typescript/require-array-sort-compare": "off", "typescript/no-misused-spread": "off", - "typescript/no-base-to-string": "off" + "typescript/no-base-to-string": "off", + "typescript/await-thenable": "off" } } From e9534787faa8983642af4e5654c7045edf93bcec Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Mon, 9 Mar 2026 17:32:08 -0400 Subject: [PATCH 16/22] lint: fix await-thenable warnings Remove unnecessary await on serializeEnvelope (returns sync value). Suppress remaining await-thenable in cron callbacks and server action instrumentation where callbacks may be async at runtime despite types. Co-Authored-By: Claude Opus 4.6 --- packages/browser/src/transports/offline.ts | 4 ++-- packages/nextjs/src/common/withServerActionInstrumentation.ts | 1 + packages/node-core/src/cron/node-cron.ts | 1 + packages/node-core/src/cron/node-schedule.ts | 1 + .../solidstart/src/server/withServerActionInstrumentation.ts | 1 + packages/sveltekit/src/vite/sourceMaps.ts | 1 + 6 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/browser/src/transports/offline.ts b/packages/browser/src/transports/offline.ts index a334268eaa69..c644e72fbf39 100644 --- a/packages/browser/src/transports/offline.ts +++ b/packages/browser/src/transports/offline.ts @@ -127,7 +127,7 @@ function createIndexedDbStore(options: BrowserOfflineTransportOptions): OfflineS return { push: async (env: Envelope) => { try { - const serialized = await serializeEnvelope(env); + const serialized = serializeEnvelope(env); await push(getStore(), serialized, options.maxQueueSize || 30); } catch { // @@ -135,7 +135,7 @@ function createIndexedDbStore(options: BrowserOfflineTransportOptions): OfflineS }, unshift: async (env: Envelope) => { try { - const serialized = await serializeEnvelope(env); + const serialized = serializeEnvelope(env); await unshift(getStore(), serialized, options.maxQueueSize || 30); } catch { // diff --git a/packages/nextjs/src/common/withServerActionInstrumentation.ts b/packages/nextjs/src/common/withServerActionInstrumentation.ts index 2096d1004e01..5a2c884a8f85 100644 --- a/packages/nextjs/src/common/withServerActionInstrumentation.ts +++ b/packages/nextjs/src/common/withServerActionInstrumentation.ts @@ -120,6 +120,7 @@ async function withServerActionInstrumentationImplementation { + // oxlint-disable-next-line typescript/await-thenable -- callback may be async at runtime const result = await handleCallbackErrors(callback, error => { if (isNotFoundNavigationError(error)) { // We don't want to report "not-found"s diff --git a/packages/node-core/src/cron/node-cron.ts b/packages/node-core/src/cron/node-cron.ts index 763b260353cf..71bf2d913313 100644 --- a/packages/node-core/src/cron/node-cron.ts +++ b/packages/node-core/src/cron/node-cron.ts @@ -58,6 +58,7 @@ export function instrumentNodeCron( // We have to manually catch here and capture the exception because node-cron swallows errors // https://github.com/node-cron/node-cron/issues/399 try { + // oxlint-disable-next-line typescript/await-thenable -- callback may be async at runtime return await callback(...args); } catch (e) { captureException(e, { diff --git a/packages/node-core/src/cron/node-schedule.ts b/packages/node-core/src/cron/node-schedule.ts index 35db51618b9a..f174ef7c904b 100644 --- a/packages/node-core/src/cron/node-schedule.ts +++ b/packages/node-core/src/cron/node-schedule.ts @@ -49,6 +49,7 @@ export function instrumentNodeSchedule(lib: T & NodeSchedule): T { return withMonitor( monitorSlug, async () => { + // oxlint-disable-next-line typescript/await-thenable -- callback may be async at runtime await callback?.(); }, { diff --git a/packages/solidstart/src/server/withServerActionInstrumentation.ts b/packages/solidstart/src/server/withServerActionInstrumentation.ts index 753188f805c3..bcd9389a6bf4 100644 --- a/packages/solidstart/src/server/withServerActionInstrumentation.ts +++ b/packages/solidstart/src/server/withServerActionInstrumentation.ts @@ -42,6 +42,7 @@ export async function withServerActionInstrumentation { + // oxlint-disable-next-line typescript/await-thenable -- callback may be async at runtime const result = await handleCallbackErrors(callback, error => { if (!isRedirect(error)) { span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' }); diff --git a/packages/sveltekit/src/vite/sourceMaps.ts b/packages/sveltekit/src/vite/sourceMaps.ts index 52f72bac3e52..ac29d436c43d 100644 --- a/packages/sveltekit/src/vite/sourceMaps.ts +++ b/packages/sveltekit/src/vite/sourceMaps.ts @@ -82,6 +82,7 @@ export async function makeCustomSentryVitePlugins( const { debug } = mergedOptions; + // oxlint-disable-next-line typescript/await-thenable -- sentryVitePlugin may return a Promise in some versions const sentryPlugins: Plugin[] = await sentryVitePlugin(mergedOptions); // In @sentry/vite-plugin v5, all functionality is consolidated into a single 'sentry-vite-plugin'. From d3c7bad776946cd6de578f65c0528d82402e8917 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Tue, 10 Mar 2026 09:54:12 -0400 Subject: [PATCH 17/22] lint: simplify optional chaining in client and transport files --- packages/core/src/client.ts | 3 +-- packages/core/src/integrations/mcp-server/transport.ts | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/core/src/client.ts b/packages/core/src/client.ts index 644b851e42c3..8209d47c0640 100644 --- a/packages/core/src/client.ts +++ b/packages/core/src/client.ts @@ -1321,8 +1321,7 @@ export abstract class Client { throw _makeDoNotSendEventError('An event processor returned `null`, will not send event.'); } - // oxlint-disable-next-line typescript/prefer-optional-chain - const isInternalException = hint.data && (hint.data as { __sentry__: boolean }).__sentry__ === true; + const isInternalException = (hint.data as { __sentry__?: boolean })?.__sentry__ === true; if (isInternalException) { return prepared; } diff --git a/packages/core/src/integrations/mcp-server/transport.ts b/packages/core/src/integrations/mcp-server/transport.ts index 065fb44ab17d..5e4fd6e75c23 100644 --- a/packages/core/src/integrations/mcp-server/transport.ts +++ b/packages/core/src/integrations/mcp-server/transport.ts @@ -105,7 +105,6 @@ export function wrapTransportSend(transport: MCPTransport, options: ResolvedMcpO } if (isJsonRpcResponse(message)) { - // oxlint-disable-next-line typescript/prefer-optional-chain if (message.id !== null && message.id !== undefined) { if (message.error) { captureJsonRpcErrorResponse(message.error); From 96a4f319e39238d1110caa2a1a253a8b85c581dc Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Tue, 10 Mar 2026 09:54:27 -0400 Subject: [PATCH 18/22] chore: remove unused jest rules configs --- .oxlintrc.json | 11 ----------- .../suites/tracing/tedious/test.ts | 1 - packages/core/test/lib/client.test.ts | 2 -- 3 files changed, 14 deletions(-) diff --git a/.oxlintrc.json b/.oxlintrc.json index fc71599097f8..677370c81e2c 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -32,23 +32,12 @@ "import/namespace": "off", "import/no-unresolved": "off", - // === Jest/Vitest rules === - "jest/no-focused-tests": "error", - "jest/no-disabled-tests": "error", - // === Rules turned off (not enforced in ESLint or causing false positives) === "no-control-regex": "off", "jsdoc/check-tag-names": "off", "jsdoc/require-yields": "off", "no-useless-rename": "off", "no-constant-binary-expression": "off", - "jest/no-conditional-expect": "off", - "jest/expect-expect": "off", - "jest/no-standalone-expect": "off", - "jest/require-to-throw-message": "off", - "jest/valid-title": "off", - "jest/no-export": "off", - "jest/valid-describe-callback": "off", "vitest/hoisted-apis-on-top": "off", "vitest/no-conditional-tests": "off", "no-unsafe-optional-chaining": "off", diff --git a/dev-packages/node-integration-tests/suites/tracing/tedious/test.ts b/dev-packages/node-integration-tests/suites/tracing/tedious/test.ts index de78cdf978aa..4b64611ac8f2 100644 --- a/dev-packages/node-integration-tests/suites/tracing/tedious/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/tedious/test.ts @@ -1,7 +1,6 @@ import { afterAll, describe, expect, test } from 'vitest'; import { cleanupChildProcesses, createRunner } from '../../../utils/runner'; -// eslint-disable-next-line jest/no-disabled-tests describe.skip('tedious auto instrumentation', { timeout: 75_000 }, () => { afterAll(() => { cleanupChildProcesses(); diff --git a/packages/core/test/lib/client.test.ts b/packages/core/test/lib/client.test.ts index e7335f0de7e0..1548a4aecce4 100644 --- a/packages/core/test/lib/client.test.ts +++ b/packages/core/test/lib/client.test.ts @@ -2816,8 +2816,6 @@ describe('Client', () => { // We could set "NODE_OPTIONS='--unhandled-rejections=warn' but it // would affect the entire test suite. // Maybe this can be re-enabled when switching to vitest. - // - // eslint-disable-next-line jest/no-disabled-tests test.skip('handles asynchronous errors', async () => { const error = new Error('Test error'); const callback = vi.fn().mockRejectedValue(error); From 52179c476a04ca0977c4b726d2047833c43e35a6 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Tue, 10 Mar 2026 09:58:52 -0400 Subject: [PATCH 19/22] chore: no longer needed ignore --- packages/core/src/tracing/google-genai/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/src/tracing/google-genai/index.ts b/packages/core/src/tracing/google-genai/index.ts index 369fb7701bd9..7781b67d6db0 100644 --- a/packages/core/src/tracing/google-genai/index.ts +++ b/packages/core/src/tracing/google-genai/index.ts @@ -143,7 +143,6 @@ function addPrivateRequestAttributes(span: Span, params: Record // config.systemInstruction: ContentUnion if ( - // oxlint-disable-next-line typescript/prefer-optional-chain 'config' in params && params.config && typeof params.config === 'object' && From 3fcaf65f5529cd3b84bfdce04290c7a145785f98 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Tue, 10 Mar 2026 10:06:47 -0400 Subject: [PATCH 20/22] lint: remove unused ignores --- packages/angular/src/errorhandler.ts | 3 +-- packages/angular/src/zone.ts | 2 +- packages/astro/src/integration/snippets.ts | 2 -- .../src/integrations/local-variables/local-variables-sync.ts | 1 - packages/node-core/src/integrations/local-variables/worker.ts | 1 - packages/sveltekit/src/server-common/handle.ts | 1 - 6 files changed, 2 insertions(+), 8 deletions(-) diff --git a/packages/angular/src/errorhandler.ts b/packages/angular/src/errorhandler.ts index ccd918667f00..1309ede53775 100644 --- a/packages/angular/src/errorhandler.ts +++ b/packages/angular/src/errorhandler.ts @@ -26,8 +26,7 @@ export interface ErrorHandlerOptions { function tryToUnwrapZonejsError(error: unknown): unknown | Error { // TODO: once Angular14 is the minimum requirement ERROR_ORIGINAL_ERROR and // getOriginalError from error.ts can be used directly. - // oxlint-disable-next-line typescript/prefer-optional-chain - return error && (error as { ngOriginalError: Error }).ngOriginalError + return (error as { ngOriginalError?: Error })?.ngOriginalError ? (error as { ngOriginalError: Error }).ngOriginalError : error; } diff --git a/packages/angular/src/zone.ts b/packages/angular/src/zone.ts index fb4db2ed8ac2..22f56e4c3871 100644 --- a/packages/angular/src/zone.ts +++ b/packages/angular/src/zone.ts @@ -7,7 +7,7 @@ declare const Zone: any; // In Angular 17 and future versions, zoneless support is forthcoming. // Therefore, it's advisable to safely check whether the `run` function is // available in the `` context. -// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access typescript/prefer-optional-chain +// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access const isNgZoneEnabled = typeof Zone !== 'undefined' && Zone.root?.run; /** diff --git a/packages/astro/src/integration/snippets.ts b/packages/astro/src/integration/snippets.ts index c97ca2fd1ed0..82278da28925 100644 --- a/packages/astro/src/integration/snippets.ts +++ b/packages/astro/src/integration/snippets.ts @@ -59,7 +59,6 @@ const buildClientIntegrations = (options: SentryOptions): string => { integrations.push('Sentry.browserTracingIntegration()'); } - /* oxlint-disable typescript/prefer-optional-chain */ if ( options.replaysSessionSampleRate == null || options.replaysSessionSampleRate || @@ -68,7 +67,6 @@ const buildClientIntegrations = (options: SentryOptions): string => { ) { integrations.push('Sentry.replayIntegration()'); } - /* oxlint-enable typescript/prefer-optional-chain */ return integrations.join(', '); }; diff --git a/packages/node-core/src/integrations/local-variables/local-variables-sync.ts b/packages/node-core/src/integrations/local-variables/local-variables-sync.ts index 406391f658d2..f40a3939593d 100644 --- a/packages/node-core/src/integrations/local-variables/local-variables-sync.ts +++ b/packages/node-core/src/integrations/local-variables/local-variables-sync.ts @@ -205,7 +205,6 @@ class AsyncSession implements DebugSession { private _unrollOther(prop: Runtime.PropertyDescriptor, vars: Variables, next: (vars: Variables) => void): void { if (prop.value) { if ('value' in prop.value) { - // oxlint-disable-next-line typescript/prefer-optional-chain if (prop.value.value === undefined || prop.value.value === null) { vars[prop.name] = `<${prop.value.value}>`; } else { diff --git a/packages/node-core/src/integrations/local-variables/worker.ts b/packages/node-core/src/integrations/local-variables/worker.ts index c0e7b5f07bde..304c7d527ef7 100644 --- a/packages/node-core/src/integrations/local-variables/worker.ts +++ b/packages/node-core/src/integrations/local-variables/worker.ts @@ -46,7 +46,6 @@ function unrollOther(prop: Runtime.PropertyDescriptor, vars: Variables): void { } if ('value' in prop.value) { - // oxlint-disable-next-line typescript/prefer-optional-chain if (prop.value.value === undefined || prop.value.value === null) { vars[prop.name] = `<${prop.value.value}>`; } else { diff --git a/packages/sveltekit/src/server-common/handle.ts b/packages/sveltekit/src/server-common/handle.ts index 761445739305..26872a0f6f24 100644 --- a/packages/sveltekit/src/server-common/handle.ts +++ b/packages/sveltekit/src/server-common/handle.ts @@ -254,7 +254,6 @@ export function sentryHandle(handlerOptions?: SentryHandleOptions): Handle { // Escape hatch to suppress request isolation and trace continuation (see initCloudflareSentryHandle) const skipIsolation = - // oxlint-disable-next-line typescript/prefer-optional-chain '_sentrySkipRequestIsolation' in backwardsForwardsCompatibleEvent.locals && backwardsForwardsCompatibleEvent.locals._sentrySkipRequestIsolation; From dbf0ee57a89a50a26971c2ac18c5d23ec87cb4c2 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Tue, 10 Mar 2026 10:15:22 -0400 Subject: [PATCH 21/22] lint: revert exact prop types changes --- .oxlintrc.json | 1 + packages/astro/src/index.types.ts | 4 ++-- packages/core/src/client.ts | 8 ++++---- packages/core/src/tracing/sentryNonRecordingSpan.ts | 2 +- packages/core/src/tracing/sentrySpan.ts | 2 +- packages/core/src/utils/hasSpansEnabled.ts | 4 +++- packages/core/src/utils/url.ts | 4 ++-- packages/deno/src/client.ts | 2 +- .../integrations/local-variables/local-variables-sync.ts | 2 +- packages/node-core/src/light/client.ts | 2 +- packages/node-core/src/sdk/client.ts | 2 +- 11 files changed, 18 insertions(+), 15 deletions(-) diff --git a/.oxlintrc.json b/.oxlintrc.json index 677370c81e2c..ef23a888fab8 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -43,6 +43,7 @@ "no-unsafe-optional-chaining": "off", "no-eval": "off", "no-import-assign": "off", + "typescript/no-duplicate-type-constituents": "off", // === Custom SDK rules (via JS plugin) === "sdk/no-eq-empty": "error" diff --git a/packages/astro/src/index.types.ts b/packages/astro/src/index.types.ts index 3958d4bc0c59..2e51ab1b0f1e 100644 --- a/packages/astro/src/index.types.ts +++ b/packages/astro/src/index.types.ts @@ -24,8 +24,8 @@ export declare const contextLinesIntegration: typeof clientSdk.contextLinesInteg export declare const getDefaultIntegrations: (options: Options) => Integration[]; export declare const defaultStackParser: StackParser; -export declare function close(timeout?: number): PromiseLike; -export declare function flush(timeout?: number): PromiseLike; +export declare function close(timeout?: number | undefined): PromiseLike; +export declare function flush(timeout?: number | undefined): PromiseLike; export declare const Span: clientSdk.Span; diff --git a/packages/core/src/client.ts b/packages/core/src/client.ts index 8209d47c0640..8d69411aacfd 100644 --- a/packages/core/src/client.ts +++ b/packages/core/src/client.ts @@ -637,7 +637,7 @@ export abstract class Client { * Receives an Event & EventHint as arguments. * @returns {() => void} A function that, when executed, removes the registered callback. */ - public on(hook: 'beforeSendEvent', callback: (event: Event, hint?: EventHint) => void): () => void; + public on(hook: 'beforeSendEvent', callback: (event: Event, hint?: EventHint | undefined) => void): () => void; /** * Register a callback for before sending a session or session aggregrates.. @@ -652,7 +652,7 @@ export abstract class Client { * Receives an Event & EventHint as arguments. * @returns {() => void} A function that, when executed, removes the registered callback. */ - public on(hook: 'preprocessEvent', callback: (event: Event, hint?: EventHint) => void): () => void; + public on(hook: 'preprocessEvent', callback: (event: Event, hint?: EventHint | undefined) => void): () => void; /** * Register a callback for postprocessing an event, @@ -660,7 +660,7 @@ export abstract class Client { * Receives an Event & EventHint as arguments. * @returns {() => void} A function that, when executed, removes the registered callback. */ - public on(hook: 'postprocessEvent', callback: (event: Event, hint?: EventHint) => void): () => void; + public on(hook: 'postprocessEvent', callback: (event: Event, hint?: EventHint | undefined) => void): () => void; /** * Register a callback for when an event has been sent. @@ -1321,7 +1321,7 @@ export abstract class Client { throw _makeDoNotSendEventError('An event processor returned `null`, will not send event.'); } - const isInternalException = (hint.data as { __sentry__?: boolean })?.__sentry__ === true; + const isInternalException = (hint.data as { __sentry__: boolean })?.__sentry__ === true; if (isInternalException) { return prepared; } diff --git a/packages/core/src/tracing/sentryNonRecordingSpan.ts b/packages/core/src/tracing/sentryNonRecordingSpan.ts index 7fbd7623215f..2f65e0eb8c08 100644 --- a/packages/core/src/tracing/sentryNonRecordingSpan.ts +++ b/packages/core/src/tracing/sentryNonRecordingSpan.ts @@ -85,7 +85,7 @@ export class SentryNonRecordingSpan implements Span { * @hidden * @internal */ - public recordException(_exception: unknown, _time?: number): void { + public recordException(_exception: unknown, _time?: number | undefined): void { // noop } } diff --git a/packages/core/src/tracing/sentrySpan.ts b/packages/core/src/tracing/sentrySpan.ts index f4ebbe00d104..9bd98b9741c6 100644 --- a/packages/core/src/tracing/sentrySpan.ts +++ b/packages/core/src/tracing/sentrySpan.ts @@ -138,7 +138,7 @@ export class SentrySpan implements Span { * @hidden * @internal */ - public recordException(_exception: unknown, _time?: number): void { + public recordException(_exception: unknown, _time?: number | undefined): void { // noop } diff --git a/packages/core/src/utils/hasSpansEnabled.ts b/packages/core/src/utils/hasSpansEnabled.ts index cf01f7ffb5ef..cfa447fd86bd 100644 --- a/packages/core/src/utils/hasSpansEnabled.ts +++ b/packages/core/src/utils/hasSpansEnabled.ts @@ -20,7 +20,9 @@ declare const __SENTRY_TRACING__: boolean | undefined; * @param maybeOptions An SDK options object to be passed to this function. * If this option is not provided, the function will use the current client's options. */ -export function hasSpansEnabled(maybeOptions?: Pick): boolean { +export function hasSpansEnabled( + maybeOptions?: Pick | undefined, +): boolean { if (typeof __SENTRY_TRACING__ === 'boolean' && !__SENTRY_TRACING__) { return false; } diff --git a/packages/core/src/utils/url.ts b/packages/core/src/utils/url.ts index 9514b3bee4be..bf0c17dbc278 100644 --- a/packages/core/src/utils/url.ts +++ b/packages/core/src/utils/url.ts @@ -16,7 +16,7 @@ type PartialURL = { }; interface URLwithCanParse extends URL { - canParse: (url: string, base?: string | URL) => boolean; + canParse: (url: string, base?: string | URL | undefined) => boolean; } // A subset of the URL object that is valid for relative URLs @@ -60,7 +60,7 @@ export function isURLObjectRelative(url: URLObject): url is RelativeURL { * @param url - The URL to parse * @returns The parsed URL object or undefined if the URL is invalid */ -export function parseStringToURLObject(url: string, urlBase?: string | URL): URLObject | undefined { +export function parseStringToURLObject(url: string, urlBase?: string | URL | undefined): URLObject | undefined { const isRelative = url.indexOf('://') <= 0 && url.indexOf('//') !== 0; const base = urlBase ?? (isRelative ? DEFAULT_BASE_URL : undefined); try { diff --git a/packages/deno/src/client.ts b/packages/deno/src/client.ts index b5de02f792ee..36886c8d5a5e 100644 --- a/packages/deno/src/client.ts +++ b/packages/deno/src/client.ts @@ -69,7 +69,7 @@ export class DenoClient extends ServerRuntimeClient { /** @inheritDoc */ // @ts-expect-error - PromiseLike is a subset of Promise - public async close(timeout?: number): PromiseLike { + public async close(timeout?: number | undefined): PromiseLike { if (this._logOnExitFlushListener) { globalThis.removeEventListener('unload', this._logOnExitFlushListener); } diff --git a/packages/node-core/src/integrations/local-variables/local-variables-sync.ts b/packages/node-core/src/integrations/local-variables/local-variables-sync.ts index f40a3939593d..b2af37b0c7fb 100644 --- a/packages/node-core/src/integrations/local-variables/local-variables-sync.ts +++ b/packages/node-core/src/integrations/local-variables/local-variables-sync.ts @@ -100,7 +100,7 @@ class AsyncSession implements DebugSession { // } - public static async create(orDefault?: DebugSession): Promise { + public static async create(orDefault?: DebugSession | undefined): Promise { if (orDefault) { return orDefault; } diff --git a/packages/node-core/src/light/client.ts b/packages/node-core/src/light/client.ts index 237e38019799..074f5231009e 100644 --- a/packages/node-core/src/light/client.ts +++ b/packages/node-core/src/light/client.ts @@ -62,7 +62,7 @@ export class LightNodeClient extends ServerRuntimeClient { /** @inheritDoc */ // @ts-expect-error - PromiseLike is a subset of Promise - public async close(timeout?: number): PromiseLike { + public async close(timeout?: number | undefined): PromiseLike { if (this._clientReportInterval) { clearInterval(this._clientReportInterval); } diff --git a/packages/node-core/src/sdk/client.ts b/packages/node-core/src/sdk/client.ts index bc706d2fe888..80a233aa3954 100644 --- a/packages/node-core/src/sdk/client.ts +++ b/packages/node-core/src/sdk/client.ts @@ -101,7 +101,7 @@ export class NodeClient extends ServerRuntimeClient { /** @inheritDoc */ // @ts-expect-error - PromiseLike is a subset of Promise - public async close(timeout?: number): PromiseLike { + public async close(timeout?: number | undefined): PromiseLike { if (this._clientReportInterval) { clearInterval(this._clientReportInterval); } From e3b947591b32e7a821926a1db00e7bc1c2200938 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Tue, 10 Mar 2026 10:40:00 -0400 Subject: [PATCH 22/22] lint: remove unused error catch param --- dev-packages/browser-integration-tests/utils/replayHelpers.ts | 4 ++-- .../suites/tracing/google-genai/scenario.mjs | 2 +- dev-packages/node-overhead-gh-action/index.mjs | 2 +- dev-packages/size-limit-gh-action/index.mjs | 2 +- packages/cloudflare/test/workflow.test.ts | 2 +- packages/core/src/utils/exports.ts | 4 ++-- .../google-cloud-serverless/test/gcpfunction/http.test.ts | 2 +- .../src/integrations/tracing/anthropic-ai/instrumentation.ts | 4 ++-- .../node/src/integrations/tracing/openai/instrumentation.ts | 4 ++-- packages/nuxt/src/runtime/plugins/storage.server.ts | 2 +- packages/remix/src/client/remixRouteParameterization.ts | 2 +- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/dev-packages/browser-integration-tests/utils/replayHelpers.ts b/dev-packages/browser-integration-tests/utils/replayHelpers.ts index 23ab2dab6400..408a3aadc933 100644 --- a/dev-packages/browser-integration-tests/utils/replayHelpers.ts +++ b/dev-packages/browser-integration-tests/utils/replayHelpers.ts @@ -364,7 +364,7 @@ export function replayEnvelopeIsCompressed(resOrReq: Request | Response): boolea const lines: boolean[] = envelopeString.split('\n').map(line => { try { JSON.parse(line); - } catch (_error) { + } catch { // If we fail to parse a line, we _might_ have found a compressed payload, // so let's check if this is actually the case. // This is quite hacky but we can't go through `line` because the prior operations @@ -394,7 +394,7 @@ export const replayEnvelopeParser = (request: Request | null): unknown[] => { const lines = envelopeString.split('\n').map(line => { try { return JSON.parse(line); - } catch (_error) { + } catch { // If we fail to parse a line, we _might_ have found a compressed payload, // so let's check if this is actually the case. // This is quite hacky but we can't go through `line` because the prior operations diff --git a/dev-packages/node-integration-tests/suites/tracing/google-genai/scenario.mjs b/dev-packages/node-integration-tests/suites/tracing/google-genai/scenario.mjs index ea5a2b33b05a..2d7a09e6f638 100644 --- a/dev-packages/node-integration-tests/suites/tracing/google-genai/scenario.mjs +++ b/dev-packages/node-integration-tests/suites/tracing/google-genai/scenario.mjs @@ -102,7 +102,7 @@ async function run() { }, ], }); - } catch (_error) { + } catch { // Expected error } }); diff --git a/dev-packages/node-overhead-gh-action/index.mjs b/dev-packages/node-overhead-gh-action/index.mjs index 6e04a9f98850..8c3e2c56873b 100644 --- a/dev-packages/node-overhead-gh-action/index.mjs +++ b/dev-packages/node-overhead-gh-action/index.mjs @@ -157,7 +157,7 @@ async function run() { body, }); } - } catch (_error) { + } catch { core.error( "Error updating comment. This can happen for PR's originating from a fork without write permissions.", ); diff --git a/dev-packages/size-limit-gh-action/index.mjs b/dev-packages/size-limit-gh-action/index.mjs index c40b4dfe0cb5..86cbcd21a793 100644 --- a/dev-packages/size-limit-gh-action/index.mjs +++ b/dev-packages/size-limit-gh-action/index.mjs @@ -171,7 +171,7 @@ async function run() { body, }); } - } catch (_error) { + } catch { core.error( "Error updating comment. This can happen for PR's originating from a fork without write permissions.", ); diff --git a/packages/cloudflare/test/workflow.test.ts b/packages/cloudflare/test/workflow.test.ts index f42331c1095a..b460e6bfee5a 100644 --- a/packages/cloudflare/test/workflow.test.ts +++ b/packages/cloudflare/test/workflow.test.ts @@ -26,7 +26,7 @@ const mockStep: WorkflowStep = { } else { return await (maybeCallback ? maybeCallback() : Promise.resolve()); } - } catch (_error) { + } catch { await new Promise(resolve => setTimeout(resolve, 1000)); } } diff --git a/packages/core/src/utils/exports.ts b/packages/core/src/utils/exports.ts index 72bdb4eb1623..fbfdea94cff4 100644 --- a/packages/core/src/utils/exports.ts +++ b/packages/core/src/utils/exports.ts @@ -21,7 +21,7 @@ export function replaceExports( // Replace the named export - handle read-only properties try { exports[exportName] = wrappedConstructor; - } catch (_error) { + } catch { // If direct assignment fails, override the property descriptor Object.defineProperty(exports, exportName, { value: wrappedConstructor, @@ -35,7 +35,7 @@ export function replaceExports( if (exports.default === original) { try { exports.default = wrappedConstructor; - } catch (_error) { + } catch { Object.defineProperty(exports, 'default', { value: wrappedConstructor, writable: true, diff --git a/packages/google-cloud-serverless/test/gcpfunction/http.test.ts b/packages/google-cloud-serverless/test/gcpfunction/http.test.ts index 3132b70ebd7e..30f6b5af68ce 100644 --- a/packages/google-cloud-serverless/test/gcpfunction/http.test.ts +++ b/packages/google-cloud-serverless/test/gcpfunction/http.test.ts @@ -63,7 +63,7 @@ describe('GCPFunction', () => { try { fn(req, res); - } catch (_error) { + } catch { res.end(); } }); diff --git a/packages/node/src/integrations/tracing/anthropic-ai/instrumentation.ts b/packages/node/src/integrations/tracing/anthropic-ai/instrumentation.ts index 5adadb577f80..48060018248c 100644 --- a/packages/node/src/integrations/tracing/anthropic-ai/instrumentation.ts +++ b/packages/node/src/integrations/tracing/anthropic-ai/instrumentation.ts @@ -89,7 +89,7 @@ export class SentryAnthropicAiInstrumentation extends InstrumentationBase