Repository navigation
Closed
Closed
Copy link
Description
Problem
The vercelAIIntegration in @sentry/nextjs doesn't activate on Vercel deployments, causing AI SDK spans to have incorrect names:
- On Vercel: Raw span names like
ai.toolCall,ai.streamText(WRONG) - Locally: Transformed names like
gen_ai.execute_tool,gen_ai.stream_text(CORRECT)
Root Cause
The Node SDK's vercelAIIntegration has conditional activation logic in afterAllSetup:
// packages/node/src/integrations/tracing/vercelai/index.ts:28-37
afterAllSetup(client) {
const shouldForce = options.force ?? shouldForceIntegration(client);
if (shouldForce) {
addVercelAiProcessors(client); // ← Span transformation enabled
} else {
instrumentation?.callWhenPatched(() => addVercelAiProcessors(client));
}
}addVercelAiProcessors is only called if:
force: trueis passed, OR- Module detection succeeds (CJS mode only), OR
- OTEL successfully patches the
aimodule
Why It Fails on Vercel
The ai package is intentionally NOT externalized in Next.js builds:
// packages/nextjs/src/config/withSentryConfig/constants.ts:5-8
// NOTE: 'ai' (Vercel AI SDK) is intentionally NOT included in this list.
// When externalized, Next.js doesn't properly handle the package's conditional exports,
// specifically the "react-server" export condition.Because ai is bundled (not externalized):
- OTEL's require hooks can't intercept module loading
instrumentation?.callWhenPatched()callback never fires- Module detection via
shouldForceIntegrationfails (requires CJS mode) - Result:
addVercelAiProcessors()is never called on Vercel
Comparison: Edge vs Node Implementation
Edge implementation (vercel-edge/src/integrations/tracing/vercelai.ts):
setup(client) {
addVercelAiProcessors(client); // ALWAYS called unconditionally
}Node implementation - conditional, requires force: true to guarantee activation in bundled environments.
Current Workaround
Users must explicitly add force: true in their server config:
// sentry.server.config.ts
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: "...",
integrations: [Sentry.vercelAIIntegration({ force: true })],
});Suggested Fix
Consider one of these approaches:
- Auto-detect Vercel environment: Default
force: truewhenVERCELenv var is present - Document the workaround: Add clear documentation that
force: trueis required for Vercel deployments - Change default behavior: Make the Node implementation behave like Edge (always register processors)
Environment
@sentry/nextjs: Latest- Deployment: Vercel (serverless)
- AI SDK:
aipackage from Vercel
Metadata
Metadata
Assignees
Projects
- StatusShow more project fieldsNo status
Activity
linear commentedon Feb 3, 2026
JS-1627
sergical commentedon Feb 3, 2026
Not sure if the
react-serverissue was fixed, if so, we can probably add it back and then it should work without passing the integration explicitely#16736
RulaKhaled commentedon Feb 6, 2026
updates here: The root cause here is that shouldForceIntegration() checks for 'ai' package by reading package.json from the filesystem. In serverless cold starts, filesystem isn't ready yet → read fails silently → empty result cached. So the integration isn't enforced by default due to missing
aipackage in the package.json. We are investigating a proper solution.fix(nextjs): Populate __SENTRY_SERVER_MODULES__ in Turbopack (#19231)
github-actions commentedon Feb 16, 2026
A PR closing this issue has just been released 🚀
This issue was referenced by PR #19231, which was included in the 10.39.0 release.
sergical commentedon Jun 4, 2026
Reopening — this still reproduces on Next.js 16 + Turbopack production builds (e.g. Vercel) on
@sentry/nextjs@10.56.0. The symptom: AI SDK spans stay as rawai.*(op: default) instead of being transformed togen_ai.*.vercelAIIntegration({ force: true })is still required as a workaround.#19231 fixed the injection side (Turbopack now emits the value-injection rule), but the consumer can't see it. Root cause:
packages/node-core/src/integrations/modules.tscaptures the value into a module-levelconstat evaluation time:That's correct for webpack (
DefinePluginreplaces the token with a literal at build time), but Turbopack assignsglobalThis.__SENTRY_SERVER_MODULES__at runtime from theinstrumentation.*value-injection loader — and the instrumentation file's ESM imports are hoisted above that assignment. Verified in a real Turbopack build (.next/server/chunks/[root-of-the-server]__*.js):So
modules.tsevaluates before the global is set,SERVER_MODULESfreezes to{}, and the othercollectModules()sources are also empty on a bundled server (no full-dependencypackage.jsonatprocess.cwd();aibundled so absent fromrequire.cache; ESM not CJS). Net:getModules().aiisundefined→shouldForceIntegrationisfalse→addVercelAiProcessorsnever attaches. This affects all module-detection-based auto integrations (Vercel AI, OpenAI, Anthropic, Google GenAI, LangChain, LangGraph), not just Vercel AI, and also leavesevent.modulesempty on Turbopack.Why CI didn't catch it: #19231's test asserts the config rule is generated (config-layer unit test), and the
nextjs-16AI E2E passes via theprocess.cwd()package.json fallback under localnext start— which is unavailable on Vercel.Fix in #21339: read
__SENTRY_SERVER_MODULES__lazily, supporting both the webpack token and the Turbopack runtime global, plus a regression test that fails on the old module-eval capture.s1gr1d commentedon Jun 8, 2026
Thanks for re-opening and the detailed debugging description! We'll take a look.
fix(node-core): Read `__SENTRY_SERVER_MODULES__` lazily so Turbopack …