sentry-javascript icon indicating copy to clipboard operation
sentry-javascript copied to clipboard

Next.js Monorepo Build Fails After Sentry 8.7.0 Upgrade Due to Module Resolution Error

Open Palmaswell opened this issue 1 year ago • 9 comments

Is there an existing issue for this?

  • [X] I have checked for existing issues https://github.com/getsentry/sentry-javascript/issues
  • [X] I have reviewed the documentation https://docs.sentry.io/
  • [X] I am using the latest SDK release https://github.com/getsentry/sentry-javascript/releases

How do you use Sentry?

Sentry Saas (sentry.io)

Which SDK are you using?

@sentry/nextjs

SDK Version

8.7.0

Framework Version

@sentry/nextjs@^8.7.0", @sentry/node@^8.7.0, @sentry/profiling-node@^8.7.0

Link to Sentry event

No response

SDK Setup

Client


import * as Sentry from "@sentry/nextjs";
const SENTRY_DSN =
  process.env.SENTRY_DSN ||
  process.env.NEXT_PUBLIC_SENTRY_DSN;

Sentry.init({
  enabled: process.env.VERCEL_ENV === "production",
  dsn: SENTRY_DSN,
  tracesSampleRate: 0.8,
  replaysSessionSampleRate: 0.1,
  replaysOnErrorSampleRate: 1.0,
  // Note: if you want to override the automatic release value, do not set a
  // `release` value here - use the environment variable `SENTRY_RELEASE`, so
  // that it will also get attached to your source maps
});

Sentry.addEventProcessor((event, hint) => {
  if (hint.originalException?.logs) {
    event.tags ??= {};
    event.tags["squads-program-error"] = true;
    event.extra = {
      ...event.extra,
      programLogs: hint.originalException.logs,
    };
  }

  return event;
});

Instrumentation.ts

import * as Sentry from "@sentry/nextjs";

const SENTRY_DSN =
  process.env.SENTRY_DSN ||
  process.env.NEXT_PUBLIC_SENTRY_DSN;

export async function register() {
  if (process.env.NEXT_RUNTIME === "nodejs") {
    const { nodeProfilingIntegration } = await import("@sentry/profiling-node");

    Sentry.init({
      enabled: process.env.VERCEL_ENV === "production",
      dsn: SENTRY_DSN,
      tracesSampleRate: 0.8,
      profilesSampleRate: 1.0,
      integrations: [nodeProfilingIntegration()],
    });
  }

  if (process.env.NEXT_RUNTIME === "edge") {
    Sentry.init({
      enabled: process.env.VERCEL_ENV === "production",
      dsn: SENTRY_DSN,
      tracesSampleRate: 0.8,
    });
  }
}

Next.JS Config

import { withSentryConfig } from "@sentry/nextjs";
import { createVanillaExtractPlugin } from "@vanilla-extract/next-plugin";

const withVanillaExtract = createVanillaExtractPlugin({
  outputCss: true,
});

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  transpilePackages: ["@squads/ui"],
  experimental: {
    instrumentationHook: true,
    serverComponentsExternalPackages: ["@sentry/profiling-node"],
  },
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "**",
      },
    ],
  },
  redirects: async () => {
    return [{ source: "/", destination: "/squads", permanent: true }];
  },
  webpack: (config, { nextRuntime }) => {
    if (nextRuntime === "edge") {
      config.externals.push({
        "node:crypto": "{}",
        stream: "{}",
      });
    }
    
    config.externals.push({
      "@sentry/profiling-node": "commonjs @sentry/profiling-node",
    });

    config.resolve.fallback = {
      ...config.resolve.fallback, 
      fs: false, 
    };
    return config;
  },
};

export default withSentryConfig(withVanillaExtract(nextConfig), { 
    silent: true, 
    hideSourceMaps: true 
    },
);

Steps to Reproduce

With meticulous attention, I diligently followed all the steps outlined in the documentation to address the issue.

  1. First, I upgraded to the latest seven versions (7.116.0) and then diligently fixed all deprecations in the project's Next.js package.
  2. I introduced the Next.js instrumentation file and imported the server and edge runtime configurations. Until this step, everything was working fine in our Yarn multi-package (mono) repo.
  3. We upgraded the packages mentioned above from 7.116.0 to 8.7.0.
  4. Removed the server and edge configuration files and moved the configuration to the instrumentation file.
  5. I updated the withSentryConfig in the Next.js config, as it now only accepts two arguments.
  6. Dynamically imported integrations module to the corresponding environment if statement.
  7. Rebuild mono repo packages with yarn.
  8. At this point, I could no longer build the Next.js project next build. Running dev was still possible, though, next start.

Expected Result

I expect to successfully upgrade the three packages and start and build the Next.js package as usual.

Actual Result

I continuously get the same error when running a next build.

Please note that I also tried:

  1. Upgrading to a different 8 version, like 8.0.0.
  2. Remove the @sentry/profiling-node package.
  3. Delete the yarn.lock file, all without success.
web:build:    Generating static pages (0/6) ...


TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type number (96184)
--
17:59:05.576 | web:build:     at new NodeError (node:internal/errors:405:5)
17:59:05.576 | web:build:     at validateString (node:internal/validators:162:11)
17:59:05.576 | web:build:     at Object.dirname (node:path:1275:5)
17:59:05.576 | web:build:     at 765218 (/vercel/path0/apps/web/.next/server/chunks/1074.js:156:349959)
17:59:05.576 | web:build:     at t (/vercel/path0/apps/web/.next/server/webpack-runtime.js:1:479)
17:59:05.576 | web:build:     at 841124 (/vercel/path0/apps/web/.next/server/chunks/1074.js:156:345522)
17:59:05.576 | web:build:     at t (/vercel/path0/apps/web/.next/server/webpack-runtime.js:1:479)
17:59:05.576 | web:build:     at 530195 (/vercel/path0/apps/web/.next/server/chunks/1074.js:156:342144)
17:59:05.576 | web:build:     at t (/vercel/path0/apps/web/.next/server/webpack-runtime.js:1:479)
17:59:05.576 | web:build:     at 853099 (/vercel/path0/apps/web/.next/server/chunks/1074.js:6:14349) {
17:59:05.577 | web:build:   code: 'ERR_INVALID_ARG_TYPE'
17:59:05.577 | web:build: }

web:build: Error occurred prerendering page "/_not-found". Read more: https://nextjs.org/docs/messages/prerender-error
web:build: 
web:build: TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type number (96184)
web:build:     at new NodeError (node:internal/errors:405:5)
web:build:     at validateString (node:internal/validators:162:11)
web:build:     at Object.dirname (node:path:1275:5)
web:build:     at 765218 (/vercel/path0/apps/web/.next/server/chunks/1074.js:156:349959)
web:build:     at t (/vercel/path0/apps/web/.next/server/webpack-runtime.js:1:479)
web:build:     at 841124 (/vercel/path0/apps/web/.next/server/chunks/1074.js:156:345522)
web:build:     at t (/vercel/path0/apps/web/.next/server/webpack-runtime.js:1:479)
web:build:     at 530195 (/vercel/path0/apps/web/.next/server/chunks/1074.js:156:342144)
web:build:     at t (/vercel/path0/apps/web/.next/server/webpack-runtime.js:1:479)
web:build:     at 853099 (/vercel/path0/apps/web/.next/server/chunks/1074.js:6:14349)


TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type number (96184)
--
17:59:08.346 | web:build:     at new NodeError (node:internal/errors:405:5)
17:59:08.346 | web:build:     at validateString (node:internal/validators:162:11)
17:59:08.346 | web:build:     at Object.dirname (node:path:1275:5)
17:59:08.346 | web:build:     at 765218 (/vercel/path0/apps/web/.next/server/chunks/1074.js:156:349959)
17:59:08.346 | web:build:     at t (/vercel/path0/apps/web/.next/server/webpack-runtime.js:1:479)
17:59:08.346 | web:build:     at 841124 (/vercel/path0/apps/web/.next/server/chunks/1074.js:156:345522)
17:59:08.346 | web:build:     at t (/vercel/path0/apps/web/.next/server/webpack-runtime.js:1:479)
17:59:08.346 | web:build:     at 530195 (/vercel/path0/apps/web/.next/server/chunks/1074.js:156:342144)
17:59:08.346 | web:build:     at t (/vercel/path0/apps/web/.next/server/webpack-runtime.js:1:479)
17:59:08.346 | web:build:     at 853099 (/vercel/path0/apps/web/.next/server/chunks/1074.js:6:14349) {
17:59:08.346 | web:build:   code: 'ERR_INVALID_ARG_TYPE'
17:59:08.346 | web:build: }


web:build: Error occurred prerendering page "/create-squad". Read more: https://nextjs.org/docs/messages/prerender-error
--
17:59:08.346 | web:build:
17:59:08.346 | web:build: TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type number (96184)
17:59:08.346 | web:build:     at new NodeError (node:internal/errors:405:5)
17:59:08.346 | web:build:     at validateString (node:internal/validators:162:11)
17:59:08.347 | web:build:     at Object.dirname (node:path:1275:5)
17:59:08.347 | web:build:     at 765218 (/vercel/path0/apps/web/.next/server/chunks/1074.js:156:349959)
17:59:08.347 | web:build:     at t (/vercel/path0/apps/web/.next/server/webpack-runtime.js:1:479)
17:59:08.347 | web:build:     at 841124 (/vercel/path0/apps/web/.next/server/chunks/1074.js:156:345522)
17:59:08.347 | web:build:     at t (/vercel/path0/apps/web/.next/server/webpack-runtime.js:1:479)
17:59:08.347 | web:build:     at 530195 (/vercel/path0/apps/web/.next/server/chunks/1074.js:156:342144)
17:59:08.347 | web:build:     at t (/vercel/path0/apps/web/.next/server/webpack-runtime.js:1:479)
17:59:08.347 | web:build:     at 853099 (/vercel/path0/apps/web/.next/server/chunks/1074.js:6:14349)
17:59:08.347 | web:build:     Generating static pages (2/6)
17:59:08.347 | web:build:     Generating static pages (4/6)

web:build: > Export encountered errors on following paths:
web:build: 	/_not-found
web:build: 	/create-squad/page: /create-squad
web:build: 	/squads/page: /squad

Palmaswell avatar Jun 05 '24 07:06 Palmaswell

Hi, can you try and make out from the stack trace and maybe with source map where this error comes from? A way to reproduce this somehow would also be awesome! Thanks!

lforst avatar Jun 06 '24 10:06 lforst

Hi @lforst, thanks so much for you prompt reply.

I tried vizualizing the stack trace for the TypeError [ERR_INVALID_ARG_TYPE] error. As you can see in the images below the error orginates in the @opentelemetry/instrumentation/build/esm/instrumentation.js in the runSpanCustomizationHook and ends in Node's resolve/lib/core as effectively shown in the source map vizualization it receives path.dirname(96184). I hope this can help us get any further.

Below the images from top to bottom like in the stack trace:

at 765218 (/Users/mau/Repos/Squads/squads/apps/web/.next/server/chunks/3426.js:157:349959) Screenshot 2024-06-10 at 13 01 04

at 841124 (/Users/mau/Repos/Squads/squads/apps/web/.next/server/chunks/3426.js:157:345522) Screenshot 2024-06-10 at 13 00 28

** at 530195 (/Users/mau/Repos/Squads/squads/apps/web/.next/server/chunks/3426.js:157:342144)** Screenshot 2024-06-10 at 13 00 02

at 110401 (/Users/mau/Repos/Squads/squads/apps/web/.next/server/chunks/3426.js:6:14780

Screenshot 2024-06-10 at 12 58 36

Please let me know anything else I can do to solve the issue.

Palmaswell avatar Jun 10 '24 11:06 Palmaswell

Thanks a bunch for providing the resolved code! I think all frames except for the top one resolved weirdly though. I don't have a solution to this yet but this seems like a buggy mixture of opentelemetry/webpack to me. Webpack seems to be turning require.resolve('is-core-module/package.json') into 96184.

Do you have any other plugins/configurations that may influence module resolution? Maybe something like a json file resolver?

lforst avatar Jun 11 '24 07:06 lforst

Please take a look at our Next.js config below. The only thing I can think about is the config resolve fallback we currently require for an NPM module.

import { withSentryConfig } from "@sentry/nextjs";
import { createVanillaExtractPlugin } from "@vanilla-extract/next-plugin";

const withVanillaExtract = createVanillaExtractPlugin({
  outputCss: true,
});

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  transpilePackages: ["@squads/ui"],
  experimental: {
    instrumentationHook: true,
    serverComponentsExternalPackages: ["@sentry/profiling-node"],
  },
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "**",
      },
    ],
  },
  redirects: async () => {
    return [{ source: "/", destination: "/squads", permanent: true }];
  },
  webpack: (config, { nextRuntime, isServer }) => {
    if (nextRuntime === "edge") {
      // This is equivalent to { fallback: {"node:crypto": false} }
      config.externals.push({
        "node:crypto": "{}",
        stream: "{}",
      });
    }

    config.externals.push({
      "@sentry/profiling-node": "commonjs @sentry/profiling-node",
    });

    if (!isServer) {
      config.resolve.fallback = {
        ...config.resolve.fallback,
        fs: false,
      };
    }
    return config;
  },
};

export default withSentryConfig(
  withVanillaExtract(nextConfig),
  { authToken: process.env.SENTRY_AUTH_TOKEN, silent: true },
  { hideSourceMaps: true }
);

Palmaswell avatar Jun 12 '24 09:06 Palmaswell

Hey @Palmaswell, unfortunately our NextJS experts are out for a couple of days but we'll take another detailed look on Monday (cc @lforst and @s1gr1d and sorry for the ping 😬).

Just an observation: Looks like you added the third parameter to withSentryConfig again which won't have an effect for v8. You should move the option to the 2nd parameter although this probably won't fix the issue.

Lms24 avatar Jun 13 '24 12:06 Lms24

I honestly don't know what is going on here. Would you mind sharing a reproduction example? Something feels off, considering the source maps are also broken.

lforst avatar Jun 17 '24 09:06 lforst

Hi @lforst, what do you mean by a reproduction example? I would appreciate it if you could be more specific. Thanks again.

Palmaswell avatar Jun 18 '24 09:06 Palmaswell

@Palmaswell Ideally something like a Repo we can pull or a Stackblitz where we can reproduce this error with clear instructions.

lforst avatar Jun 19 '24 11:06 lforst

Unfortunately, I can't share the repo as it's private for the organization I work for. I will prepare a reproduction on Stackblitz in the next couple of days.

Palmaswell avatar Jun 20 '24 08:06 Palmaswell

@Palmaswell did y'all ever figure out a fix for this? I'm having this on a brand new repo.

cvoege avatar Jul 10 '24 14:07 cvoege

@cvoege would you mind sharing something we can use to reproduce locally?

lforst avatar Jul 11 '24 07:07 lforst

@Palmaswell did y'all ever figure out a fix for this? I'm having this on a brand new repo.

No, we were not able to fix this yet. It would be really great if you could share the team so they can reproduce.

Palmaswell avatar Jul 11 '24 07:07 Palmaswell

This issue has gone three weeks without activity. In another week, I will close it.

But! If you comment or otherwise update it, I will reset the clock, and if you remove the label Waiting for: Community, I will leave it alone ... forever!


"A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀

getsantry[bot] avatar Aug 09 '24 07:08 getsantry[bot]

@cvoege were you able to resolve the issue?

Palmaswell avatar Aug 09 '24 07:08 Palmaswell