@@ -10,15 +10,20 @@ export const instrumentVercelAi = generateInstrumentOnce(INTEGRATION_NAME, () =>
1010/**
1111 * Determines if the 'ai' package is installed and available.
1212 *
13- * Uses require.resolve() to check for package availability without loading it.
14- * This approach avoids race conditions that can occur with filesystem-based
15- * detection during initialization in serverless environments (Lambda/Vercel).
13+ * Uses dynamic property access to hide require.resolve from bundler static analysis.
14+ * This prevents webpack from trying to resolve 'ai' at build time while
15+ * still allowing runtime detection.
16+ *
17+ * We use this instead of modulesIntegration because in Next.js v16 with Turbopack,
18+ * the modules list is empty at initialization time (race condition).
1619 *
1720 * @returns true if the 'ai' package can be resolved, false otherwise
1821 */
1922function shouldForceIntegration ( ) : boolean {
2023 try {
21- require . resolve ( 'ai' ) ;
24+ const req = require ;
25+ const resolve = req [ 'resolve' ] ;
26+ resolve ( 'ai' ) ;
2227 return true ;
2328 } catch {
2429 return false ;
@@ -36,13 +41,12 @@ const _vercelAIIntegration = ((options: VercelAiOptions = {}) => {
3641 } ,
3742 afterAllSetup ( client ) {
3843 // Auto-detect if we should force the integration when the 'ai' package is available
39- // Uses require.resolve() for reliable detection in all environments
44+ // Uses dynamic property access for bundler-safe detection
4045 const shouldForce = options . force ?? shouldForceIntegration ( ) ;
4146
4247 if ( shouldForce ) {
4348 addVercelAiProcessors ( client ) ;
4449 } else {
45- // Lazy registration - only registers when 'ai' package is actually imported
4650 instrumentation ?. callWhenPatched ( ( ) => addVercelAiProcessors ( client ) ) ;
4751 }
4852 } ,
0 commit comments