From faa28026a0c65c6ef435ba090943a0bbec0ad808 Mon Sep 17 00:00:00 2001 From: "sentry-junior[bot]" <264270552+sentry-junior[bot]@users.noreply.github.com> Date: Wed, 21 Oct 2026 17:24:37 +0000 Subject: [PATCH 1/2] fix(v10): Fix CI breakage from `@opentelemetry/api` 1.10.0 `@opentelemetry/api` 1.10.0 widened `Attributes` values to `AnyValue`, and a 1.10 copy ignores globals registered by a 1.9 copy. This broke three things on v10: - `wrapSamplingDecision` rejected the `Attributes` a custom sampler receives in `shouldSample`. It now accepts OTel `Attributes`. - Vercel AI v6 integration tests: `ai` pulled its own 1.10 copy into the tmp install, so its spans never reached Sentry. The runner now pins `@opentelemetry/api` in tmp installs to the SDK's version. - node-otel-without-tracing pins 1.9.0 while `@sentry/node` resolved 1.10.0. The app now overrides `@opentelemetry/api` so only one copy is installed. Co-Authored-By: Lukas Stracke --- .../node-otel-without-tracing/package.json | 5 ++++ .../utils/runner/createEsmAndCjsTests.ts | 23 +++++++++++++++++-- packages/opentelemetry/src/sampler.ts | 8 ++++--- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/package.json b/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/package.json index 04a6a80a500c..a57b40615487 100644 --- a/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/package.json +++ b/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/package.json @@ -27,6 +27,11 @@ "@playwright/test": "~1.56.0", "@sentry-internal/test-utils": "link:../../../test-utils" }, + "pnpm": { + "overrides": { + "@opentelemetry/api": "1.9.0" + } + }, "volta": { "extends": "../../package.json" } diff --git a/dev-packages/node-integration-tests/utils/runner/createEsmAndCjsTests.ts b/dev-packages/node-integration-tests/utils/runner/createEsmAndCjsTests.ts index e480bbc1b68f..2003872d395c 100644 --- a/dev-packages/node-integration-tests/utils/runner/createEsmAndCjsTests.ts +++ b/dev-packages/node-integration-tests/utils/runner/createEsmAndCjsTests.ts @@ -1,7 +1,7 @@ import { exec } from 'child_process'; -import { existsSync } from 'fs'; +import { existsSync, readFileSync } from 'fs'; import { cp, mkdir, readFile, rm, writeFile } from 'fs/promises'; -import { basename, join } from 'path'; +import { basename, dirname, join } from 'path'; import { promisify } from 'util'; import { afterAll, beforeAll, test, type TestAPI } from 'vitest'; import { CLEANUP_STEPS, createRunner } from './createRunner'; @@ -292,6 +292,9 @@ experimentalUseDiagnosticsChannelInjection();`, private: true, version: '0.0.0', dependencies: additionalDependencies, + // Packages like `ai` depend on `@opentelemetry/api` themselves. If npm resolves a newer minor than the SDK's + // copy, the newer copy refuses the globals registered by the older one and the package's spans are dropped. + overrides: additionalDependencies['@opentelemetry/api'] ? {} : { '@opentelemetry/api': getSdkOtelApiVersion() }, } as const; await writeFile(join(tmpDirPath, 'package.json'), JSON.stringify(packageJson, null, 2)); @@ -369,6 +372,22 @@ function convertEsmToCjs(content: string): string { return newContent; } +function getSdkOtelApiVersion(): string { + const otelApiEntry = require.resolve('@opentelemetry/api', { paths: [dirname(require.resolve('@sentry/node'))] }); + let dir = dirname(otelApiEntry); + while (dir !== dirname(dir)) { + const packageJsonPath = join(dir, 'package.json'); + if (existsSync(packageJsonPath)) { + const { name, version } = JSON.parse(readFileSync(packageJsonPath, 'utf8')) as { name?: string; version: string }; + if (name === '@opentelemetry/api') { + return version; + } + } + dir = dirname(dir); + } + throw new Error(`Could not find the @opentelemetry/api version used by @sentry/node (resolved ${otelApiEntry})`); +} + const NPM_INSTALL_MAX_RETRIES = 3; const NPM_INSTALL_RETRY_DELAY_MS = 2_000; diff --git a/packages/opentelemetry/src/sampler.ts b/packages/opentelemetry/src/sampler.ts index 0d7b2acabad1..96d766782f9a 100644 --- a/packages/opentelemetry/src/sampler.ts +++ b/packages/opentelemetry/src/sampler.ts @@ -1,5 +1,5 @@ /* eslint-disable complexity */ -import type { Context, Span, TraceState as TraceStateInterface } from '@opentelemetry/api'; +import type { Attributes, Context, Span, TraceState as TraceStateInterface } from '@opentelemetry/api'; import { isSpanContextValid, SpanKind, trace } from '@opentelemetry/api'; import { TraceState } from './utils/TraceState'; import type { Sampler, SamplingResult } from '@opentelemetry/sdk-trace-base'; @@ -277,7 +277,9 @@ export function wrapSamplingDecision({ }: { decision: SamplingDecision | undefined; context: Context; - spanAttributes: SpanAttributes; + // Typed as OTel `Attributes` so custom samplers can pass their `shouldSample` attributes through, + // whichever `@opentelemetry/api` version they use (1.10 widened attribute values to `AnyValue`). + spanAttributes: Attributes; sampleRand?: number; downstreamTraceSampleRate?: number; // flags for ignored streamed spans (only set for span streaming) @@ -319,7 +321,7 @@ export function wrapSamplingDecision({ return { decision, traceState }; } -function getBaseTraceState(context: Context, spanAttributes: SpanAttributes): TraceStateInterface { +function getBaseTraceState(context: Context, spanAttributes: Attributes): TraceStateInterface { const parentSpan = trace.getSpan(context); const parentContext = parentSpan?.spanContext(); From 208ff89314fa273a155d76c2e409b6901b2bc37f Mon Sep 17 00:00:00 2001 From: "sentry-junior[bot]" <264270552+sentry-junior[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 08:12:18 +0000 Subject: [PATCH 2/2] test(v10/e2e): Bump node-otel-without-tracing to @opentelemetry/api ^1.10.0 Replaces the pnpm override so the app and @sentry/node resolve the same copy. --- .../node-otel-without-tracing/package.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/package.json b/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/package.json index a57b40615487..21beacf9fda5 100644 --- a/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/package.json +++ b/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/package.json @@ -11,7 +11,7 @@ "test:assert": "pnpm test" }, "dependencies": { - "@opentelemetry/api": "1.9.0", + "@opentelemetry/api": "^1.10.0", "@opentelemetry/sdk-trace-node": "2.6.1", "@opentelemetry/exporter-trace-otlp-http": "0.214.0", "@opentelemetry/instrumentation-undici": "0.24.0", @@ -27,11 +27,6 @@ "@playwright/test": "~1.56.0", "@sentry-internal/test-utils": "link:../../../test-utils" }, - "pnpm": { - "overrides": { - "@opentelemetry/api": "1.9.0" - } - }, "volta": { "extends": "../../package.json" }