fix(node-core): Read __SENTRY_SERVER_MODULES__ lazily so Turbopack injection is honored - #21339

Merged
sergical merged 5 commits into
developfrom
fix/node-core-turbopack-server-modules
Jun 8, 2026
Merged

fix(node-core): Read __SENTRY_SERVER_MODULES__ lazily so Turbopack injection is honored#21339
sergical merged 5 commits into
developfrom
fix/node-core-turbopack-server-modules

Conversation

@sergical

Copy link
Copy Markdown
Member

Summary

Fixes the root cause behind #19147. On Next.js 16 / Turbopack production builds (e.g. Vercel), modulesIntegration returns no injected modules, which silently disables every module-detection-based auto integration — vercelAIIntegration, openAIIntegration, anthropicAIIntegration, googleGenAIIntegration, langChainIntegration, langGraphIntegration — and leaves event.modules missing server dependencies. The result users see: raw ai.* spans (op: default) instead of gen_ai.*.

Root cause

packages/node-core/src/integrations/modules.ts captured the injected value into a module-level const at evaluation time:

constSERVER_MODULES=typeof__SENTRY_SERVER_MODULES__==='undefined' ? {} : __SENTRY_SERVER_MODULES__;

The two bundlers inject __SENTRY_SERVER_MODULES__ differently:

The catch: the instrumentation.* file's ESM imports are hoisted above the injected assignment. Verified in a real Turbopack build (.next/server/chunks/[root-of-the-server]__*.js):

769449,e=>{"use strict";varr=e.i(298962);// import @sentry/* — evaluates modules.ts (SERVER_MODULES captured = {})asyncfunctions(){awaite.A(145684)}// register()globalThis.__SENTRY_SERVER_MODULES__={/* …deps… */}// injection runs AFTER the import}

So @sentry/node-core/modules evaluates before the global is assigned, and the const is frozen as {}. The other two sources in collectModules() also come up empty on a bundled server (no full-dependency package.json at process.cwd(); ai is bundled so it's not in require.cache, and the server is ESM not CJS). Net: getModules().ai is undefinedshouldForceIntegration returns falseaddVercelAiProcessors never attaches.

Why #19231 didn't catch it

#19231 was unit-tested at the config-generation layer (asserting the value-injection rule is emitted). The nextjs-16 AI E2E that asserts gen_ai.* spans passes for the wrong reason — it runs next startlocally, where getModulesFromPackageJson() reads process.cwd()/package.json (present, lists ai) and masks the broken SERVER_MODULES path. On Vercel that fallback is empty, so detection fails.

Fix

Read the value lazily (per call) instead of capturing it at module-eval time, and support both injection styles:

functiongetServerModules(): Record<string,string>{if(typeof__SENTRY_SERVER_MODULES__!=='undefined')return__SENTRY_SERVER_MODULES__;// webpackreturn(GLOBAL_OBJas ...).__SENTRY_SERVER_MODULES__??{};// turbopack}

By the time getModules() is first called (during integration afterAllSetup, i.e. after register()Sentry.init()), the instrumentation module body has fully executed and the global is set. webpack is unaffected (token still replaced).

Regression test

packages/node-core/test/integrations/modules.test.ts re-imports the module with no global set (mirroring Turbopack), then assigns globalThis.__SENTRY_SERVER_MODULES__after import and asserts getModules() reflects it. This fails on the previous code and passes with the fix.

Blast radius

Low. webpack path unchanged; Turbopack now honored; event.modules restored on Turbopack. Re-enables all module-detection-based auto integrations on Next.js 16 without requiring vercelAIIntegration({ force: true }).

Follow-up (separate)

The existing nextjs-16 AI E2E should be hardened so it can't pass via the process.cwd() package.json fallback — e.g. a --turbopack build variant run from a working directory whose package.json does not list the AI SDK, asserting gen_ai.* spans still appear. Happy to do this in a follow-up.

🤖 Generated with Claude Code

…jection is honored
`modulesIntegration` captured `__SENTRY_SERVER_MODULES__` into a module-level
`const` at evaluation time. That works for webpack (DefinePlugin replaces the
token with a literal at build time) but not for Turbopack: the value-injection
loader assigns `globalThis.__SENTRY_SERVER_MODULES__` at runtime, and the
instrumentation file's ESM imports are hoisted above that assignment — so this
module evaluates before the global is set and the capture is always empty.
As a result, on Next.js 16 / Turbopack production builds (e.g. Vercel) every
module-detection-based auto integration silently never activates
(vercelAI, openAI, anthropic, googleGenAI, langChain, langGraph), and
`event.modules` is missing server dependencies.
Read the value lazily instead: prefer the build-time-replaced token (webpack),
then fall back to `GLOBAL_OBJ.__SENTRY_SERVER_MODULES__` (Turbopack). Adds a
regression test that fails when the value is captured at module-eval time.
Ref: #19147
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sergical
sergical requested a review from a team as a code ownerJune 4, 2026 19:18
@sergical
sergical requested review from JPeer264 and andreiborza and removed request for a teamJune 4, 2026 19:18
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@s1gr1d
s1gr1d requested a review from nicohrubecJune 8, 2026 07:22

@s1gr1ds1gr1d left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me - thanks for the fix. I checked the test and it would fail with the old behavior so this should help us protect against regressions in the future.

Comment on lines +15 to +27
* Reads the modules that were injected at build time into `__SENTRY_SERVER_MODULES__`
* (e.g. by the Next.js SDK, to work around not having access to these at runtime).
*
* This MUST be read lazily (on every call) rather than captured once at module-evaluation
* time, because the two supported bundlers inject the value differently:
* - webpack replaces the `__SENTRY_SERVER_MODULES__` token with a literal via `DefinePlugin`
* (available as soon as this module is evaluated).
* - Turbopack assigns `globalThis.__SENTRY_SERVER_MODULES__` at runtime, from a value-injection
* loader applied to `instrumentation.*`. The instrumentation file's ESM imports are hoisted
* above that assignment, so this module is evaluated *before* the global is set. A
* module-level `const` capture would therefore always be empty under Turbopack, silently
* disabling every module-detection-based auto integration (Vercel AI, OpenAI, Anthropic,
* Google GenAI, LangChain, LangGraph). See getsentry/sentry-javascript#19147.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this comment can be shortened a bit as it's very exhaustive.

sergicaland others added 2 commits June 8, 2026 06:20
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…opack-server-modules
# Conflicts:
#	CHANGELOG.md
@sergical
sergical enabled auto-merge (squash) June 8, 2026 10:31
@sergical
sergical merged commit 99988a8 into developJun 8, 2026
191 of 192 checks passed
@sergical
sergical deleted the fix/node-core-turbopack-server-modules branch June 8, 2026 10:47
@Lms24

Lms24 commented Jun 9, 2026

Copy link
Copy Markdown
Member

For posterity, because it took quite some time to figure out what this PR actually fixes:

  • Fixes a timing issue when reading the build-time-injected __SENTRY_SERVER_MODULES__ constant in NextJS 16 Turbopack. Reading the constant at import time is too early, since the value is only populated later. This fix delays the reading to event processing time of modulesIntegration.
  • This fixes two issues:

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@sergical@Lms24@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix(node-core): Read __SENTRY_SERVER_MODULES__ lazily so Turbopack injection is honored - #21339

Merged
sergical merged 5 commits into
developfrom
fix/node-core-turbopack-server-modules
Jun 8, 2026
Merged

fix(node-core): Read __SENTRY_SERVER_MODULES__ lazily so Turbopack injection is honored#21339
sergical merged 5 commits into
developfrom
fix/node-core-turbopack-server-modules

Conversation

@sergical

Copy link
Copy Markdown
Member

Summary

Fixes the root cause behind #19147. On Next.js 16 / Turbopack production builds (e.g. Vercel), modulesIntegration returns no injected modules, which silently disables every module-detection-based auto integration — vercelAIIntegration, openAIIntegration, anthropicAIIntegration, googleGenAIIntegration, langChainIntegration, langGraphIntegration — and leaves event.modules missing server dependencies. The result users see: raw ai.* spans (op: default) instead of gen_ai.*.

Root cause

packages/node-core/src/integrations/modules.ts captured the injected value into a module-level const at evaluation time:

constSERVER_MODULES=typeof__SENTRY_SERVER_MODULES__==='undefined' ? {} : __SENTRY_SERVER_MODULES__;

The two bundlers inject __SENTRY_SERVER_MODULES__ differently:

The catch: the instrumentation.* file's ESM imports are hoisted above the injected assignment. Verified in a real Turbopack build (.next/server/chunks/[root-of-the-server]__*.js):

769449,e=>{"use strict";varr=e.i(298962);// import @sentry/* — evaluates modules.ts (SERVER_MODULES captured = {})asyncfunctions(){awaite.A(145684)}// register()globalThis.__SENTRY_SERVER_MODULES__={/* …deps… */}// injection runs AFTER the import}

So @sentry/node-core/modules evaluates before the global is assigned, and the const is frozen as {}. The other two sources in collectModules() also come up empty on a bundled server (no full-dependency package.json at process.cwd(); ai is bundled so it's not in require.cache, and the server is ESM not CJS). Net: getModules().ai is undefinedshouldForceIntegration returns falseaddVercelAiProcessors never attaches.

Why #19231 didn't catch it

#19231 was unit-tested at the config-generation layer (asserting the value-injection rule is emitted). The nextjs-16 AI E2E that asserts gen_ai.* spans passes for the wrong reason — it runs next startlocally, where getModulesFromPackageJson() reads process.cwd()/package.json (present, lists ai) and masks the broken SERVER_MODULES path. On Vercel that fallback is empty, so detection fails.

Fix

Read the value lazily (per call) instead of capturing it at module-eval time, and support both injection styles:

functiongetServerModules(): Record<string,string>{if(typeof__SENTRY_SERVER_MODULES__!=='undefined')return__SENTRY_SERVER_MODULES__;// webpackreturn(GLOBAL_OBJas ...).__SENTRY_SERVER_MODULES__??{};// turbopack}

By the time getModules() is first called (during integration afterAllSetup, i.e. after register()Sentry.init()), the instrumentation module body has fully executed and the global is set. webpack is unaffected (token still replaced).

Regression test

packages/node-core/test/integrations/modules.test.ts re-imports the module with no global set (mirroring Turbopack), then assigns globalThis.__SENTRY_SERVER_MODULES__after import and asserts getModules() reflects it. This fails on the previous code and passes with the fix.

Blast radius

Low. webpack path unchanged; Turbopack now honored; event.modules restored on Turbopack. Re-enables all module-detection-based auto integrations on Next.js 16 without requiring vercelAIIntegration({ force: true }).

Follow-up (separate)

The existing nextjs-16 AI E2E should be hardened so it can't pass via the process.cwd() package.json fallback — e.g. a --turbopack build variant run from a working directory whose package.json does not list the AI SDK, asserting gen_ai.* spans still appear. Happy to do this in a follow-up.

🤖 Generated with Claude Code

…jection is honored
`modulesIntegration` captured `__SENTRY_SERVER_MODULES__` into a module-level
`const` at evaluation time. That works for webpack (DefinePlugin replaces the
token with a literal at build time) but not for Turbopack: the value-injection
loader assigns `globalThis.__SENTRY_SERVER_MODULES__` at runtime, and the
instrumentation file's ESM imports are hoisted above that assignment — so this
module evaluates before the global is set and the capture is always empty.
As a result, on Next.js 16 / Turbopack production builds (e.g. Vercel) every
module-detection-based auto integration silently never activates
(vercelAI, openAI, anthropic, googleGenAI, langChain, langGraph), and
`event.modules` is missing server dependencies.
Read the value lazily instead: prefer the build-time-replaced token (webpack),
then fall back to `GLOBAL_OBJ.__SENTRY_SERVER_MODULES__` (Turbopack). Adds a
regression test that fails when the value is captured at module-eval time.
Ref: #19147
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sergical
sergical requested a review from a team as a code ownerJune 4, 2026 19:18
@sergical
sergical requested review from JPeer264 and andreiborza and removed request for a teamJune 4, 2026 19:18
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@s1gr1d
s1gr1d requested a review from nicohrubecJune 8, 2026 07:22

@s1gr1ds1gr1d left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me - thanks for the fix. I checked the test and it would fail with the old behavior so this should help us protect against regressions in the future.

Comment on lines +15 to +27
* Reads the modules that were injected at build time into `__SENTRY_SERVER_MODULES__`
* (e.g. by the Next.js SDK, to work around not having access to these at runtime).
*
* This MUST be read lazily (on every call) rather than captured once at module-evaluation
* time, because the two supported bundlers inject the value differently:
* - webpack replaces the `__SENTRY_SERVER_MODULES__` token with a literal via `DefinePlugin`
* (available as soon as this module is evaluated).
* - Turbopack assigns `globalThis.__SENTRY_SERVER_MODULES__` at runtime, from a value-injection
* loader applied to `instrumentation.*`. The instrumentation file's ESM imports are hoisted
* above that assignment, so this module is evaluated *before* the global is set. A
* module-level `const` capture would therefore always be empty under Turbopack, silently
* disabling every module-detection-based auto integration (Vercel AI, OpenAI, Anthropic,
* Google GenAI, LangChain, LangGraph). See getsentry/sentry-javascript#19147.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this comment can be shortened a bit as it's very exhaustive.

sergicaland others added 2 commits June 8, 2026 06:20
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…opack-server-modules
# Conflicts:
#	CHANGELOG.md
@sergical
sergical enabled auto-merge (squash) June 8, 2026 10:31
@sergical
sergical merged commit 99988a8 into developJun 8, 2026
191 of 192 checks passed
@sergical
sergical deleted the fix/node-core-turbopack-server-modules branch June 8, 2026 10:47
@Lms24

Lms24 commented Jun 9, 2026

Copy link
Copy Markdown
Member

For posterity, because it took quite some time to figure out what this PR actually fixes:

  • Fixes a timing issue when reading the build-time-injected __SENTRY_SERVER_MODULES__ constant in NextJS 16 Turbopack. Reading the constant at import time is too early, since the value is only populated later. This fix delays the reading to event processing time of modulesIntegration.
  • This fixes two issues:

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@sergical@Lms24@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(node-core): Read __SENTRY_SERVER_MODULES__ lazily so Turbopack injection is honored - #21339

Merged
sergical merged 5 commits into
developfrom
fix/node-core-turbopack-server-modules
Jun 8, 2026
Merged

fix(node-core): Read __SENTRY_SERVER_MODULES__ lazily so Turbopack injection is honored#21339
sergical merged 5 commits into
developfrom
fix/node-core-turbopack-server-modules

Conversation

@sergical

Copy link
Copy Markdown
Member

Summary

Fixes the root cause behind #19147. On Next.js 16 / Turbopack production builds (e.g. Vercel), modulesIntegration returns no injected modules, which silently disables every module-detection-based auto integration — vercelAIIntegration, openAIIntegration, anthropicAIIntegration, googleGenAIIntegration, langChainIntegration, langGraphIntegration — and leaves event.modules missing server dependencies. The result users see: raw ai.* spans (op: default) instead of gen_ai.*.

Root cause

packages/node-core/src/integrations/modules.ts captured the injected value into a module-level const at evaluation time:

constSERVER_MODULES=typeof__SENTRY_SERVER_MODULES__==='undefined' ? {} : __SENTRY_SERVER_MODULES__;

The two bundlers inject __SENTRY_SERVER_MODULES__ differently:

The catch: the instrumentation.* file's ESM imports are hoisted above the injected assignment. Verified in a real Turbopack build (.next/server/chunks/[root-of-the-server]__*.js):

769449,e=>{"use strict";varr=e.i(298962);// import @sentry/* — evaluates modules.ts (SERVER_MODULES captured = {})asyncfunctions(){awaite.A(145684)}// register()globalThis.__SENTRY_SERVER_MODULES__={/* …deps… */}// injection runs AFTER the import}

So @sentry/node-core/modules evaluates before the global is assigned, and the const is frozen as {}. The other two sources in collectModules() also come up empty on a bundled server (no full-dependency package.json at process.cwd(); ai is bundled so it's not in require.cache, and the server is ESM not CJS). Net: getModules().ai is undefinedshouldForceIntegration returns falseaddVercelAiProcessors never attaches.

Why #19231 didn't catch it

#19231 was unit-tested at the config-generation layer (asserting the value-injection rule is emitted). The nextjs-16 AI E2E that asserts gen_ai.* spans passes for the wrong reason — it runs next startlocally, where getModulesFromPackageJson() reads process.cwd()/package.json (present, lists ai) and masks the broken SERVER_MODULES path. On Vercel that fallback is empty, so detection fails.

Fix

Read the value lazily (per call) instead of capturing it at module-eval time, and support both injection styles:

functiongetServerModules(): Record<string,string>{if(typeof__SENTRY_SERVER_MODULES__!=='undefined')return__SENTRY_SERVER_MODULES__;// webpackreturn(GLOBAL_OBJas ...).__SENTRY_SERVER_MODULES__??{};// turbopack}

By the time getModules() is first called (during integration afterAllSetup, i.e. after register()Sentry.init()), the instrumentation module body has fully executed and the global is set. webpack is unaffected (token still replaced).

Regression test

packages/node-core/test/integrations/modules.test.ts re-imports the module with no global set (mirroring Turbopack), then assigns globalThis.__SENTRY_SERVER_MODULES__after import and asserts getModules() reflects it. This fails on the previous code and passes with the fix.

Blast radius

Low. webpack path unchanged; Turbopack now honored; event.modules restored on Turbopack. Re-enables all module-detection-based auto integrations on Next.js 16 without requiring vercelAIIntegration({ force: true }).

Follow-up (separate)

The existing nextjs-16 AI E2E should be hardened so it can't pass via the process.cwd() package.json fallback — e.g. a --turbopack build variant run from a working directory whose package.json does not list the AI SDK, asserting gen_ai.* spans still appear. Happy to do this in a follow-up.

🤖 Generated with Claude Code

…jection is honored
`modulesIntegration` captured `__SENTRY_SERVER_MODULES__` into a module-level
`const` at evaluation time. That works for webpack (DefinePlugin replaces the
token with a literal at build time) but not for Turbopack: the value-injection
loader assigns `globalThis.__SENTRY_SERVER_MODULES__` at runtime, and the
instrumentation file's ESM imports are hoisted above that assignment — so this
module evaluates before the global is set and the capture is always empty.
As a result, on Next.js 16 / Turbopack production builds (e.g. Vercel) every
module-detection-based auto integration silently never activates
(vercelAI, openAI, anthropic, googleGenAI, langChain, langGraph), and
`event.modules` is missing server dependencies.
Read the value lazily instead: prefer the build-time-replaced token (webpack),
then fall back to `GLOBAL_OBJ.__SENTRY_SERVER_MODULES__` (Turbopack). Adds a
regression test that fails when the value is captured at module-eval time.
Ref: #19147
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sergical
sergical requested a review from a team as a code ownerJune 4, 2026 19:18
@sergical
sergical requested review from JPeer264 and andreiborza and removed request for a teamJune 4, 2026 19:18
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@s1gr1d
s1gr1d requested a review from nicohrubecJune 8, 2026 07:22

@s1gr1ds1gr1d left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me - thanks for the fix. I checked the test and it would fail with the old behavior so this should help us protect against regressions in the future.

Comment on lines +15 to +27
* Reads the modules that were injected at build time into `__SENTRY_SERVER_MODULES__`
* (e.g. by the Next.js SDK, to work around not having access to these at runtime).
*
* This MUST be read lazily (on every call) rather than captured once at module-evaluation
* time, because the two supported bundlers inject the value differently:
* - webpack replaces the `__SENTRY_SERVER_MODULES__` token with a literal via `DefinePlugin`
* (available as soon as this module is evaluated).
* - Turbopack assigns `globalThis.__SENTRY_SERVER_MODULES__` at runtime, from a value-injection
* loader applied to `instrumentation.*`. The instrumentation file's ESM imports are hoisted
* above that assignment, so this module is evaluated *before* the global is set. A
* module-level `const` capture would therefore always be empty under Turbopack, silently
* disabling every module-detection-based auto integration (Vercel AI, OpenAI, Anthropic,
* Google GenAI, LangChain, LangGraph). See getsentry/sentry-javascript#19147.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this comment can be shortened a bit as it's very exhaustive.

sergicaland others added 2 commits June 8, 2026 06:20
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…opack-server-modules
# Conflicts:
#	CHANGELOG.md
@sergical
sergical enabled auto-merge (squash) June 8, 2026 10:31
@sergical
sergical merged commit 99988a8 into developJun 8, 2026
191 of 192 checks passed
@sergical
sergical deleted the fix/node-core-turbopack-server-modules branch June 8, 2026 10:47
@Lms24

Lms24 commented Jun 9, 2026

Copy link
Copy Markdown
Member

For posterity, because it took quite some time to figure out what this PR actually fixes:

  • Fixes a timing issue when reading the build-time-injected __SENTRY_SERVER_MODULES__ constant in NextJS 16 Turbopack. Reading the constant at import time is too early, since the value is only populated later. This fix delays the reading to event processing time of modulesIntegration.
  • This fixes two issues:

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@sergical@Lms24@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(node-core): Read __SENTRY_SERVER_MODULES__ lazily so Turbopack injection is honored - #21339

Merged
sergical merged 5 commits into
developfrom
fix/node-core-turbopack-server-modules
Jun 8, 2026
Merged

fix(node-core): Read __SENTRY_SERVER_MODULES__ lazily so Turbopack injection is honored#21339
sergical merged 5 commits into
developfrom
fix/node-core-turbopack-server-modules

Conversation

@sergical

Copy link
Copy Markdown
Member

Summary

Fixes the root cause behind #19147. On Next.js 16 / Turbopack production builds (e.g. Vercel), modulesIntegration returns no injected modules, which silently disables every module-detection-based auto integration — vercelAIIntegration, openAIIntegration, anthropicAIIntegration, googleGenAIIntegration, langChainIntegration, langGraphIntegration — and leaves event.modules missing server dependencies. The result users see: raw ai.* spans (op: default) instead of gen_ai.*.

Root cause

packages/node-core/src/integrations/modules.ts captured the injected value into a module-level const at evaluation time:

constSERVER_MODULES=typeof__SENTRY_SERVER_MODULES__==='undefined' ? {} : __SENTRY_SERVER_MODULES__;

The two bundlers inject __SENTRY_SERVER_MODULES__ differently:

The catch: the instrumentation.* file's ESM imports are hoisted above the injected assignment. Verified in a real Turbopack build (.next/server/chunks/[root-of-the-server]__*.js):

769449,e=>{"use strict";varr=e.i(298962);// import @sentry/* — evaluates modules.ts (SERVER_MODULES captured = {})asyncfunctions(){awaite.A(145684)}// register()globalThis.__SENTRY_SERVER_MODULES__={/* …deps… */}// injection runs AFTER the import}

So @sentry/node-core/modules evaluates before the global is assigned, and the const is frozen as {}. The other two sources in collectModules() also come up empty on a bundled server (no full-dependency package.json at process.cwd(); ai is bundled so it's not in require.cache, and the server is ESM not CJS). Net: getModules().ai is undefinedshouldForceIntegration returns falseaddVercelAiProcessors never attaches.

Why #19231 didn't catch it

#19231 was unit-tested at the config-generation layer (asserting the value-injection rule is emitted). The nextjs-16 AI E2E that asserts gen_ai.* spans passes for the wrong reason — it runs next startlocally, where getModulesFromPackageJson() reads process.cwd()/package.json (present, lists ai) and masks the broken SERVER_MODULES path. On Vercel that fallback is empty, so detection fails.

Fix

Read the value lazily (per call) instead of capturing it at module-eval time, and support both injection styles:

functiongetServerModules(): Record<string,string>{if(typeof__SENTRY_SERVER_MODULES__!=='undefined')return__SENTRY_SERVER_MODULES__;// webpackreturn(GLOBAL_OBJas ...).__SENTRY_SERVER_MODULES__??{};// turbopack}

By the time getModules() is first called (during integration afterAllSetup, i.e. after register()Sentry.init()), the instrumentation module body has fully executed and the global is set. webpack is unaffected (token still replaced).

Regression test

packages/node-core/test/integrations/modules.test.ts re-imports the module with no global set (mirroring Turbopack), then assigns globalThis.__SENTRY_SERVER_MODULES__after import and asserts getModules() reflects it. This fails on the previous code and passes with the fix.

Blast radius

Low. webpack path unchanged; Turbopack now honored; event.modules restored on Turbopack. Re-enables all module-detection-based auto integrations on Next.js 16 without requiring vercelAIIntegration({ force: true }).

Follow-up (separate)

The existing nextjs-16 AI E2E should be hardened so it can't pass via the process.cwd() package.json fallback — e.g. a --turbopack build variant run from a working directory whose package.json does not list the AI SDK, asserting gen_ai.* spans still appear. Happy to do this in a follow-up.

🤖 Generated with Claude Code

…jection is honored
`modulesIntegration` captured `__SENTRY_SERVER_MODULES__` into a module-level
`const` at evaluation time. That works for webpack (DefinePlugin replaces the
token with a literal at build time) but not for Turbopack: the value-injection
loader assigns `globalThis.__SENTRY_SERVER_MODULES__` at runtime, and the
instrumentation file's ESM imports are hoisted above that assignment — so this
module evaluates before the global is set and the capture is always empty.
As a result, on Next.js 16 / Turbopack production builds (e.g. Vercel) every
module-detection-based auto integration silently never activates
(vercelAI, openAI, anthropic, googleGenAI, langChain, langGraph), and
`event.modules` is missing server dependencies.
Read the value lazily instead: prefer the build-time-replaced token (webpack),
then fall back to `GLOBAL_OBJ.__SENTRY_SERVER_MODULES__` (Turbopack). Adds a
regression test that fails when the value is captured at module-eval time.
Ref: #19147
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sergical
sergical requested a review from a team as a code ownerJune 4, 2026 19:18
@sergical
sergical requested review from JPeer264 and andreiborza and removed request for a teamJune 4, 2026 19:18
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@s1gr1d
s1gr1d requested a review from nicohrubecJune 8, 2026 07:22

@s1gr1ds1gr1d left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me - thanks for the fix. I checked the test and it would fail with the old behavior so this should help us protect against regressions in the future.

Comment on lines +15 to +27
* Reads the modules that were injected at build time into `__SENTRY_SERVER_MODULES__`
* (e.g. by the Next.js SDK, to work around not having access to these at runtime).
*
* This MUST be read lazily (on every call) rather than captured once at module-evaluation
* time, because the two supported bundlers inject the value differently:
* - webpack replaces the `__SENTRY_SERVER_MODULES__` token with a literal via `DefinePlugin`
* (available as soon as this module is evaluated).
* - Turbopack assigns `globalThis.__SENTRY_SERVER_MODULES__` at runtime, from a value-injection
* loader applied to `instrumentation.*`. The instrumentation file's ESM imports are hoisted
* above that assignment, so this module is evaluated *before* the global is set. A
* module-level `const` capture would therefore always be empty under Turbopack, silently
* disabling every module-detection-based auto integration (Vercel AI, OpenAI, Anthropic,
* Google GenAI, LangChain, LangGraph). See getsentry/sentry-javascript#19147.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this comment can be shortened a bit as it's very exhaustive.

sergicaland others added 2 commits June 8, 2026 06:20
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…opack-server-modules
# Conflicts:
#	CHANGELOG.md
@sergical
sergical enabled auto-merge (squash) June 8, 2026 10:31
@sergical
sergical merged commit 99988a8 into developJun 8, 2026
191 of 192 checks passed
@sergical
sergical deleted the fix/node-core-turbopack-server-modules branch June 8, 2026 10:47
@Lms24

Lms24 commented Jun 9, 2026

Copy link
Copy Markdown
Member

For posterity, because it took quite some time to figure out what this PR actually fixes:

  • Fixes a timing issue when reading the build-time-injected __SENTRY_SERVER_MODULES__ constant in NextJS 16 Turbopack. Reading the constant at import time is too early, since the value is only populated later. This fix delays the reading to event processing time of modulesIntegration.
  • This fixes two issues:

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@sergical@Lms24@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix(node-core): Read __SENTRY_SERVER_MODULES__ lazily so Turbopack injection is honored - #21339

Merged
sergical merged 5 commits into
developfrom
fix/node-core-turbopack-server-modules
Jun 8, 2026
Merged

fix(node-core): Read __SENTRY_SERVER_MODULES__ lazily so Turbopack injection is honored#21339
sergical merged 5 commits into
developfrom
fix/node-core-turbopack-server-modules

Conversation

@sergical

Copy link
Copy Markdown
Member

Summary

Fixes the root cause behind #19147. On Next.js 16 / Turbopack production builds (e.g. Vercel), modulesIntegration returns no injected modules, which silently disables every module-detection-based auto integration — vercelAIIntegration, openAIIntegration, anthropicAIIntegration, googleGenAIIntegration, langChainIntegration, langGraphIntegration — and leaves event.modules missing server dependencies. The result users see: raw ai.* spans (op: default) instead of gen_ai.*.

Root cause

packages/node-core/src/integrations/modules.ts captured the injected value into a module-level const at evaluation time:

constSERVER_MODULES=typeof__SENTRY_SERVER_MODULES__==='undefined' ? {} : __SENTRY_SERVER_MODULES__;

The two bundlers inject __SENTRY_SERVER_MODULES__ differently:

The catch: the instrumentation.* file's ESM imports are hoisted above the injected assignment. Verified in a real Turbopack build (.next/server/chunks/[root-of-the-server]__*.js):

769449,e=>{"use strict";varr=e.i(298962);// import @sentry/* — evaluates modules.ts (SERVER_MODULES captured = {})asyncfunctions(){awaite.A(145684)}// register()globalThis.__SENTRY_SERVER_MODULES__={/* …deps… */}// injection runs AFTER the import}

So @sentry/node-core/modules evaluates before the global is assigned, and the const is frozen as {}. The other two sources in collectModules() also come up empty on a bundled server (no full-dependency package.json at process.cwd(); ai is bundled so it's not in require.cache, and the server is ESM not CJS). Net: getModules().ai is undefinedshouldForceIntegration returns falseaddVercelAiProcessors never attaches.

Why #19231 didn't catch it

#19231 was unit-tested at the config-generation layer (asserting the value-injection rule is emitted). The nextjs-16 AI E2E that asserts gen_ai.* spans passes for the wrong reason — it runs next startlocally, where getModulesFromPackageJson() reads process.cwd()/package.json (present, lists ai) and masks the broken SERVER_MODULES path. On Vercel that fallback is empty, so detection fails.

Fix

Read the value lazily (per call) instead of capturing it at module-eval time, and support both injection styles:

functiongetServerModules(): Record<string,string>{if(typeof__SENTRY_SERVER_MODULES__!=='undefined')return__SENTRY_SERVER_MODULES__;// webpackreturn(GLOBAL_OBJas ...).__SENTRY_SERVER_MODULES__??{};// turbopack}

By the time getModules() is first called (during integration afterAllSetup, i.e. after register()Sentry.init()), the instrumentation module body has fully executed and the global is set. webpack is unaffected (token still replaced).

Regression test

packages/node-core/test/integrations/modules.test.ts re-imports the module with no global set (mirroring Turbopack), then assigns globalThis.__SENTRY_SERVER_MODULES__after import and asserts getModules() reflects it. This fails on the previous code and passes with the fix.

Blast radius

Low. webpack path unchanged; Turbopack now honored; event.modules restored on Turbopack. Re-enables all module-detection-based auto integrations on Next.js 16 without requiring vercelAIIntegration({ force: true }).

Follow-up (separate)

The existing nextjs-16 AI E2E should be hardened so it can't pass via the process.cwd() package.json fallback — e.g. a --turbopack build variant run from a working directory whose package.json does not list the AI SDK, asserting gen_ai.* spans still appear. Happy to do this in a follow-up.

🤖 Generated with Claude Code

…jection is honored
`modulesIntegration` captured `__SENTRY_SERVER_MODULES__` into a module-level
`const` at evaluation time. That works for webpack (DefinePlugin replaces the
token with a literal at build time) but not for Turbopack: the value-injection
loader assigns `globalThis.__SENTRY_SERVER_MODULES__` at runtime, and the
instrumentation file's ESM imports are hoisted above that assignment — so this
module evaluates before the global is set and the capture is always empty.
As a result, on Next.js 16 / Turbopack production builds (e.g. Vercel) every
module-detection-based auto integration silently never activates
(vercelAI, openAI, anthropic, googleGenAI, langChain, langGraph), and
`event.modules` is missing server dependencies.
Read the value lazily instead: prefer the build-time-replaced token (webpack),
then fall back to `GLOBAL_OBJ.__SENTRY_SERVER_MODULES__` (Turbopack). Adds a
regression test that fails when the value is captured at module-eval time.
Ref: #19147
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sergical
sergical requested a review from a team as a code ownerJune 4, 2026 19:18
@sergical
sergical requested review from JPeer264 and andreiborza and removed request for a teamJune 4, 2026 19:18
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@s1gr1d
s1gr1d requested a review from nicohrubecJune 8, 2026 07:22

@s1gr1ds1gr1d left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me - thanks for the fix. I checked the test and it would fail with the old behavior so this should help us protect against regressions in the future.

Comment on lines +15 to +27
* Reads the modules that were injected at build time into `__SENTRY_SERVER_MODULES__`
* (e.g. by the Next.js SDK, to work around not having access to these at runtime).
*
* This MUST be read lazily (on every call) rather than captured once at module-evaluation
* time, because the two supported bundlers inject the value differently:
* - webpack replaces the `__SENTRY_SERVER_MODULES__` token with a literal via `DefinePlugin`
* (available as soon as this module is evaluated).
* - Turbopack assigns `globalThis.__SENTRY_SERVER_MODULES__` at runtime, from a value-injection
* loader applied to `instrumentation.*`. The instrumentation file's ESM imports are hoisted
* above that assignment, so this module is evaluated *before* the global is set. A
* module-level `const` capture would therefore always be empty under Turbopack, silently
* disabling every module-detection-based auto integration (Vercel AI, OpenAI, Anthropic,
* Google GenAI, LangChain, LangGraph). See getsentry/sentry-javascript#19147.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this comment can be shortened a bit as it's very exhaustive.

sergicaland others added 2 commits June 8, 2026 06:20
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…opack-server-modules
# Conflicts:
#	CHANGELOG.md
@sergical
sergical enabled auto-merge (squash) June 8, 2026 10:31
@sergical
sergical merged commit 99988a8 into developJun 8, 2026
191 of 192 checks passed
@sergical
sergical deleted the fix/node-core-turbopack-server-modules branch June 8, 2026 10:47
@Lms24

Lms24 commented Jun 9, 2026

Copy link
Copy Markdown
Member

For posterity, because it took quite some time to figure out what this PR actually fixes:

  • Fixes a timing issue when reading the build-time-injected __SENTRY_SERVER_MODULES__ constant in NextJS 16 Turbopack. Reading the constant at import time is too early, since the value is only populated later. This fix delays the reading to event processing time of modulesIntegration.
  • This fixes two issues:

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@sergical@Lms24@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(node-core): Read __SENTRY_SERVER_MODULES__ lazily so Turbopack injection is honored - #21339

Merged
sergical merged 5 commits into
developfrom
fix/node-core-turbopack-server-modules
Jun 8, 2026
Merged

fix(node-core): Read __SENTRY_SERVER_MODULES__ lazily so Turbopack injection is honored#21339
sergical merged 5 commits into
developfrom
fix/node-core-turbopack-server-modules

Conversation

@sergical

Copy link
Copy Markdown
Member

Summary

Fixes the root cause behind #19147. On Next.js 16 / Turbopack production builds (e.g. Vercel), modulesIntegration returns no injected modules, which silently disables every module-detection-based auto integration — vercelAIIntegration, openAIIntegration, anthropicAIIntegration, googleGenAIIntegration, langChainIntegration, langGraphIntegration — and leaves event.modules missing server dependencies. The result users see: raw ai.* spans (op: default) instead of gen_ai.*.

Root cause

packages/node-core/src/integrations/modules.ts captured the injected value into a module-level const at evaluation time:

constSERVER_MODULES=typeof__SENTRY_SERVER_MODULES__==='undefined' ? {} : __SENTRY_SERVER_MODULES__;

The two bundlers inject __SENTRY_SERVER_MODULES__ differently:

The catch: the instrumentation.* file's ESM imports are hoisted above the injected assignment. Verified in a real Turbopack build (.next/server/chunks/[root-of-the-server]__*.js):

769449,e=>{"use strict";varr=e.i(298962);// import @sentry/* — evaluates modules.ts (SERVER_MODULES captured = {})asyncfunctions(){awaite.A(145684)}// register()globalThis.__SENTRY_SERVER_MODULES__={/* …deps… */}// injection runs AFTER the import}

So @sentry/node-core/modules evaluates before the global is assigned, and the const is frozen as {}. The other two sources in collectModules() also come up empty on a bundled server (no full-dependency package.json at process.cwd(); ai is bundled so it's not in require.cache, and the server is ESM not CJS). Net: getModules().ai is undefinedshouldForceIntegration returns falseaddVercelAiProcessors never attaches.

Why #19231 didn't catch it

#19231 was unit-tested at the config-generation layer (asserting the value-injection rule is emitted). The nextjs-16 AI E2E that asserts gen_ai.* spans passes for the wrong reason — it runs next startlocally, where getModulesFromPackageJson() reads process.cwd()/package.json (present, lists ai) and masks the broken SERVER_MODULES path. On Vercel that fallback is empty, so detection fails.

Fix

Read the value lazily (per call) instead of capturing it at module-eval time, and support both injection styles:

functiongetServerModules(): Record<string,string>{if(typeof__SENTRY_SERVER_MODULES__!=='undefined')return__SENTRY_SERVER_MODULES__;// webpackreturn(GLOBAL_OBJas ...).__SENTRY_SERVER_MODULES__??{};// turbopack}

By the time getModules() is first called (during integration afterAllSetup, i.e. after register()Sentry.init()), the instrumentation module body has fully executed and the global is set. webpack is unaffected (token still replaced).

Regression test

packages/node-core/test/integrations/modules.test.ts re-imports the module with no global set (mirroring Turbopack), then assigns globalThis.__SENTRY_SERVER_MODULES__after import and asserts getModules() reflects it. This fails on the previous code and passes with the fix.

Blast radius

Low. webpack path unchanged; Turbopack now honored; event.modules restored on Turbopack. Re-enables all module-detection-based auto integrations on Next.js 16 without requiring vercelAIIntegration({ force: true }).

Follow-up (separate)

The existing nextjs-16 AI E2E should be hardened so it can't pass via the process.cwd() package.json fallback — e.g. a --turbopack build variant run from a working directory whose package.json does not list the AI SDK, asserting gen_ai.* spans still appear. Happy to do this in a follow-up.

🤖 Generated with Claude Code

…jection is honored
`modulesIntegration` captured `__SENTRY_SERVER_MODULES__` into a module-level
`const` at evaluation time. That works for webpack (DefinePlugin replaces the
token with a literal at build time) but not for Turbopack: the value-injection
loader assigns `globalThis.__SENTRY_SERVER_MODULES__` at runtime, and the
instrumentation file's ESM imports are hoisted above that assignment — so this
module evaluates before the global is set and the capture is always empty.
As a result, on Next.js 16 / Turbopack production builds (e.g. Vercel) every
module-detection-based auto integration silently never activates
(vercelAI, openAI, anthropic, googleGenAI, langChain, langGraph), and
`event.modules` is missing server dependencies.
Read the value lazily instead: prefer the build-time-replaced token (webpack),
then fall back to `GLOBAL_OBJ.__SENTRY_SERVER_MODULES__` (Turbopack). Adds a
regression test that fails when the value is captured at module-eval time.
Ref: #19147
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sergical
sergical requested a review from a team as a code ownerJune 4, 2026 19:18
@sergical
sergical requested review from JPeer264 and andreiborza and removed request for a teamJune 4, 2026 19:18
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@s1gr1d
s1gr1d requested a review from nicohrubecJune 8, 2026 07:22

@s1gr1ds1gr1d left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me - thanks for the fix. I checked the test and it would fail with the old behavior so this should help us protect against regressions in the future.

Comment on lines +15 to +27
* Reads the modules that were injected at build time into `__SENTRY_SERVER_MODULES__`
* (e.g. by the Next.js SDK, to work around not having access to these at runtime).
*
* This MUST be read lazily (on every call) rather than captured once at module-evaluation
* time, because the two supported bundlers inject the value differently:
* - webpack replaces the `__SENTRY_SERVER_MODULES__` token with a literal via `DefinePlugin`
* (available as soon as this module is evaluated).
* - Turbopack assigns `globalThis.__SENTRY_SERVER_MODULES__` at runtime, from a value-injection
* loader applied to `instrumentation.*`. The instrumentation file's ESM imports are hoisted
* above that assignment, so this module is evaluated *before* the global is set. A
* module-level `const` capture would therefore always be empty under Turbopack, silently
* disabling every module-detection-based auto integration (Vercel AI, OpenAI, Anthropic,
* Google GenAI, LangChain, LangGraph). See getsentry/sentry-javascript#19147.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this comment can be shortened a bit as it's very exhaustive.

sergicaland others added 2 commits June 8, 2026 06:20
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…opack-server-modules
# Conflicts:
#	CHANGELOG.md
@sergical
sergical enabled auto-merge (squash) June 8, 2026 10:31
@sergical
sergical merged commit 99988a8 into developJun 8, 2026
191 of 192 checks passed
@sergical
sergical deleted the fix/node-core-turbopack-server-modules branch June 8, 2026 10:47
@Lms24

Lms24 commented Jun 9, 2026

Copy link
Copy Markdown
Member

For posterity, because it took quite some time to figure out what this PR actually fixes:

  • Fixes a timing issue when reading the build-time-injected __SENTRY_SERVER_MODULES__ constant in NextJS 16 Turbopack. Reading the constant at import time is too early, since the value is only populated later. This fix delays the reading to event processing time of modulesIntegration.
  • This fixes two issues:

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@sergical@Lms24@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(node-core): Read __SENTRY_SERVER_MODULES__ lazily so Turbopack injection is honored - #21339

Merged
sergical merged 5 commits into
developfrom
fix/node-core-turbopack-server-modules
Jun 8, 2026
Merged

fix(node-core): Read __SENTRY_SERVER_MODULES__ lazily so Turbopack injection is honored#21339
sergical merged 5 commits into
developfrom
fix/node-core-turbopack-server-modules

Conversation

@sergical

Copy link
Copy Markdown
Member

Summary

Fixes the root cause behind #19147. On Next.js 16 / Turbopack production builds (e.g. Vercel), modulesIntegration returns no injected modules, which silently disables every module-detection-based auto integration — vercelAIIntegration, openAIIntegration, anthropicAIIntegration, googleGenAIIntegration, langChainIntegration, langGraphIntegration — and leaves event.modules missing server dependencies. The result users see: raw ai.* spans (op: default) instead of gen_ai.*.

Root cause

packages/node-core/src/integrations/modules.ts captured the injected value into a module-level const at evaluation time:

constSERVER_MODULES=typeof__SENTRY_SERVER_MODULES__==='undefined' ? {} : __SENTRY_SERVER_MODULES__;

The two bundlers inject __SENTRY_SERVER_MODULES__ differently:

The catch: the instrumentation.* file's ESM imports are hoisted above the injected assignment. Verified in a real Turbopack build (.next/server/chunks/[root-of-the-server]__*.js):

769449,e=>{"use strict";varr=e.i(298962);// import @sentry/* — evaluates modules.ts (SERVER_MODULES captured = {})asyncfunctions(){awaite.A(145684)}// register()globalThis.__SENTRY_SERVER_MODULES__={/* …deps… */}// injection runs AFTER the import}

So @sentry/node-core/modules evaluates before the global is assigned, and the const is frozen as {}. The other two sources in collectModules() also come up empty on a bundled server (no full-dependency package.json at process.cwd(); ai is bundled so it's not in require.cache, and the server is ESM not CJS). Net: getModules().ai is undefinedshouldForceIntegration returns falseaddVercelAiProcessors never attaches.

Why #19231 didn't catch it

#19231 was unit-tested at the config-generation layer (asserting the value-injection rule is emitted). The nextjs-16 AI E2E that asserts gen_ai.* spans passes for the wrong reason — it runs next startlocally, where getModulesFromPackageJson() reads process.cwd()/package.json (present, lists ai) and masks the broken SERVER_MODULES path. On Vercel that fallback is empty, so detection fails.

Fix

Read the value lazily (per call) instead of capturing it at module-eval time, and support both injection styles:

functiongetServerModules(): Record<string,string>{if(typeof__SENTRY_SERVER_MODULES__!=='undefined')return__SENTRY_SERVER_MODULES__;// webpackreturn(GLOBAL_OBJas ...).__SENTRY_SERVER_MODULES__??{};// turbopack}

By the time getModules() is first called (during integration afterAllSetup, i.e. after register()Sentry.init()), the instrumentation module body has fully executed and the global is set. webpack is unaffected (token still replaced).

Regression test

packages/node-core/test/integrations/modules.test.ts re-imports the module with no global set (mirroring Turbopack), then assigns globalThis.__SENTRY_SERVER_MODULES__after import and asserts getModules() reflects it. This fails on the previous code and passes with the fix.

Blast radius

Low. webpack path unchanged; Turbopack now honored; event.modules restored on Turbopack. Re-enables all module-detection-based auto integrations on Next.js 16 without requiring vercelAIIntegration({ force: true }).

Follow-up (separate)

The existing nextjs-16 AI E2E should be hardened so it can't pass via the process.cwd() package.json fallback — e.g. a --turbopack build variant run from a working directory whose package.json does not list the AI SDK, asserting gen_ai.* spans still appear. Happy to do this in a follow-up.

🤖 Generated with Claude Code

…jection is honored
`modulesIntegration` captured `__SENTRY_SERVER_MODULES__` into a module-level
`const` at evaluation time. That works for webpack (DefinePlugin replaces the
token with a literal at build time) but not for Turbopack: the value-injection
loader assigns `globalThis.__SENTRY_SERVER_MODULES__` at runtime, and the
instrumentation file's ESM imports are hoisted above that assignment — so this
module evaluates before the global is set and the capture is always empty.
As a result, on Next.js 16 / Turbopack production builds (e.g. Vercel) every
module-detection-based auto integration silently never activates
(vercelAI, openAI, anthropic, googleGenAI, langChain, langGraph), and
`event.modules` is missing server dependencies.
Read the value lazily instead: prefer the build-time-replaced token (webpack),
then fall back to `GLOBAL_OBJ.__SENTRY_SERVER_MODULES__` (Turbopack). Adds a
regression test that fails when the value is captured at module-eval time.
Ref: #19147
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sergical
sergical requested a review from a team as a code ownerJune 4, 2026 19:18
@sergical
sergical requested review from JPeer264 and andreiborza and removed request for a teamJune 4, 2026 19:18
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@s1gr1d
s1gr1d requested a review from nicohrubecJune 8, 2026 07:22

@s1gr1ds1gr1d left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me - thanks for the fix. I checked the test and it would fail with the old behavior so this should help us protect against regressions in the future.

Comment on lines +15 to +27
* Reads the modules that were injected at build time into `__SENTRY_SERVER_MODULES__`
* (e.g. by the Next.js SDK, to work around not having access to these at runtime).
*
* This MUST be read lazily (on every call) rather than captured once at module-evaluation
* time, because the two supported bundlers inject the value differently:
* - webpack replaces the `__SENTRY_SERVER_MODULES__` token with a literal via `DefinePlugin`
* (available as soon as this module is evaluated).
* - Turbopack assigns `globalThis.__SENTRY_SERVER_MODULES__` at runtime, from a value-injection
* loader applied to `instrumentation.*`. The instrumentation file's ESM imports are hoisted
* above that assignment, so this module is evaluated *before* the global is set. A
* module-level `const` capture would therefore always be empty under Turbopack, silently
* disabling every module-detection-based auto integration (Vercel AI, OpenAI, Anthropic,
* Google GenAI, LangChain, LangGraph). See getsentry/sentry-javascript#19147.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this comment can be shortened a bit as it's very exhaustive.

sergicaland others added 2 commits June 8, 2026 06:20
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…opack-server-modules
# Conflicts:
#	CHANGELOG.md
@sergical
sergical enabled auto-merge (squash) June 8, 2026 10:31
@sergical
sergical merged commit 99988a8 into developJun 8, 2026
191 of 192 checks passed
@sergical
sergical deleted the fix/node-core-turbopack-server-modules branch June 8, 2026 10:47
@Lms24

Lms24 commented Jun 9, 2026

Copy link
Copy Markdown
Member

For posterity, because it took quite some time to figure out what this PR actually fixes:

  • Fixes a timing issue when reading the build-time-injected __SENTRY_SERVER_MODULES__ constant in NextJS 16 Turbopack. Reading the constant at import time is too early, since the value is only populated later. This fix delays the reading to event processing time of modulesIntegration.
  • This fixes two issues:

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@sergical@Lms24@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix(node-core): Read __SENTRY_SERVER_MODULES__ lazily so Turbopack injection is honored - #21339

Merged
sergical merged 5 commits into
developfrom
fix/node-core-turbopack-server-modules
Jun 8, 2026
Merged

fix(node-core): Read __SENTRY_SERVER_MODULES__ lazily so Turbopack injection is honored#21339
sergical merged 5 commits into
developfrom
fix/node-core-turbopack-server-modules

Conversation

@sergical

Copy link
Copy Markdown
Member

Summary

Fixes the root cause behind #19147. On Next.js 16 / Turbopack production builds (e.g. Vercel), modulesIntegration returns no injected modules, which silently disables every module-detection-based auto integration — vercelAIIntegration, openAIIntegration, anthropicAIIntegration, googleGenAIIntegration, langChainIntegration, langGraphIntegration — and leaves event.modules missing server dependencies. The result users see: raw ai.* spans (op: default) instead of gen_ai.*.

Root cause

packages/node-core/src/integrations/modules.ts captured the injected value into a module-level const at evaluation time:

constSERVER_MODULES=typeof__SENTRY_SERVER_MODULES__==='undefined' ? {} : __SENTRY_SERVER_MODULES__;

The two bundlers inject __SENTRY_SERVER_MODULES__ differently:

The catch: the instrumentation.* file's ESM imports are hoisted above the injected assignment. Verified in a real Turbopack build (.next/server/chunks/[root-of-the-server]__*.js):

769449,e=>{"use strict";varr=e.i(298962);// import @sentry/* — evaluates modules.ts (SERVER_MODULES captured = {})asyncfunctions(){awaite.A(145684)}// register()globalThis.__SENTRY_SERVER_MODULES__={/* …deps… */}// injection runs AFTER the import}

So @sentry/node-core/modules evaluates before the global is assigned, and the const is frozen as {}. The other two sources in collectModules() also come up empty on a bundled server (no full-dependency package.json at process.cwd(); ai is bundled so it's not in require.cache, and the server is ESM not CJS). Net: getModules().ai is undefinedshouldForceIntegration returns falseaddVercelAiProcessors never attaches.

Why #19231 didn't catch it

#19231 was unit-tested at the config-generation layer (asserting the value-injection rule is emitted). The nextjs-16 AI E2E that asserts gen_ai.* spans passes for the wrong reason — it runs next startlocally, where getModulesFromPackageJson() reads process.cwd()/package.json (present, lists ai) and masks the broken SERVER_MODULES path. On Vercel that fallback is empty, so detection fails.

Fix

Read the value lazily (per call) instead of capturing it at module-eval time, and support both injection styles:

functiongetServerModules(): Record<string,string>{if(typeof__SENTRY_SERVER_MODULES__!=='undefined')return__SENTRY_SERVER_MODULES__;// webpackreturn(GLOBAL_OBJas ...).__SENTRY_SERVER_MODULES__??{};// turbopack}

By the time getModules() is first called (during integration afterAllSetup, i.e. after register()Sentry.init()), the instrumentation module body has fully executed and the global is set. webpack is unaffected (token still replaced).

Regression test

packages/node-core/test/integrations/modules.test.ts re-imports the module with no global set (mirroring Turbopack), then assigns globalThis.__SENTRY_SERVER_MODULES__after import and asserts getModules() reflects it. This fails on the previous code and passes with the fix.

Blast radius

Low. webpack path unchanged; Turbopack now honored; event.modules restored on Turbopack. Re-enables all module-detection-based auto integrations on Next.js 16 without requiring vercelAIIntegration({ force: true }).

Follow-up (separate)

The existing nextjs-16 AI E2E should be hardened so it can't pass via the process.cwd() package.json fallback — e.g. a --turbopack build variant run from a working directory whose package.json does not list the AI SDK, asserting gen_ai.* spans still appear. Happy to do this in a follow-up.

🤖 Generated with Claude Code

…jection is honored
`modulesIntegration` captured `__SENTRY_SERVER_MODULES__` into a module-level
`const` at evaluation time. That works for webpack (DefinePlugin replaces the
token with a literal at build time) but not for Turbopack: the value-injection
loader assigns `globalThis.__SENTRY_SERVER_MODULES__` at runtime, and the
instrumentation file's ESM imports are hoisted above that assignment — so this
module evaluates before the global is set and the capture is always empty.
As a result, on Next.js 16 / Turbopack production builds (e.g. Vercel) every
module-detection-based auto integration silently never activates
(vercelAI, openAI, anthropic, googleGenAI, langChain, langGraph), and
`event.modules` is missing server dependencies.
Read the value lazily instead: prefer the build-time-replaced token (webpack),
then fall back to `GLOBAL_OBJ.__SENTRY_SERVER_MODULES__` (Turbopack). Adds a
regression test that fails when the value is captured at module-eval time.
Ref: #19147
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sergical
sergical requested a review from a team as a code ownerJune 4, 2026 19:18
@sergical
sergical requested review from JPeer264 and andreiborza and removed request for a teamJune 4, 2026 19:18
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@s1gr1d
s1gr1d requested a review from nicohrubecJune 8, 2026 07:22

@s1gr1ds1gr1d left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me - thanks for the fix. I checked the test and it would fail with the old behavior so this should help us protect against regressions in the future.

Comment on lines +15 to +27
* Reads the modules that were injected at build time into `__SENTRY_SERVER_MODULES__`
* (e.g. by the Next.js SDK, to work around not having access to these at runtime).
*
* This MUST be read lazily (on every call) rather than captured once at module-evaluation
* time, because the two supported bundlers inject the value differently:
* - webpack replaces the `__SENTRY_SERVER_MODULES__` token with a literal via `DefinePlugin`
* (available as soon as this module is evaluated).
* - Turbopack assigns `globalThis.__SENTRY_SERVER_MODULES__` at runtime, from a value-injection
* loader applied to `instrumentation.*`. The instrumentation file's ESM imports are hoisted
* above that assignment, so this module is evaluated *before* the global is set. A
* module-level `const` capture would therefore always be empty under Turbopack, silently
* disabling every module-detection-based auto integration (Vercel AI, OpenAI, Anthropic,
* Google GenAI, LangChain, LangGraph). See getsentry/sentry-javascript#19147.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this comment can be shortened a bit as it's very exhaustive.

sergicaland others added 2 commits June 8, 2026 06:20
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…opack-server-modules
# Conflicts:
#	CHANGELOG.md
@sergical
sergical enabled auto-merge (squash) June 8, 2026 10:31
@sergical
sergical merged commit 99988a8 into developJun 8, 2026
191 of 192 checks passed
@sergical
sergical deleted the fix/node-core-turbopack-server-modules branch June 8, 2026 10:47
@Lms24

Lms24 commented Jun 9, 2026

Copy link
Copy Markdown
Member

For posterity, because it took quite some time to figure out what this PR actually fixes:

  • Fixes a timing issue when reading the build-time-injected __SENTRY_SERVER_MODULES__ constant in NextJS 16 Turbopack. Reading the constant at import time is too early, since the value is only populated later. This fix delays the reading to event processing time of modulesIntegration.
  • This fixes two issues:

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@sergical@Lms24@s1gr1d