rollup/rollup · critical

Cannot find module ${id}. npm has a bug related to optional

Error message

Cannot find module ${id}. npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). Please use `npm i` again after removing both package-lock.json and node_modules directory.

What it means

The native addon is shipped as platform-specific optional dependencies (`@rollup/rollup-<platform-arch>`). A known npm bug (npm/cli#4828) sometimes skips installing the correct optional dependency, leaving the main package unable to require its binary. native.js wraps the bare `Cannot find module` into a recovery instruction.

Source

Thrown at native.js:121

		return require(id);
	} catch (error) {
		if (
			platform === 'win32' &&
			error instanceof Error &&
			error.code === 'ERR_DLOPEN_FAILED' &&
			error.message.includes('The specified module could not be found')
		) {
			const msvcDownloadLink = `https://aka.ms/vs/17/release/${msvcLinkFilenameByArch[arch]}`;
			throw new Error(
				`Failed to load module ${id}. ` +
					'Required DLL was not found. ' +
					'This error usually happens when Microsoft Visual C++ Redistributable is not installed. ' +
					`You can download it from ${msvcDownloadLink}`,
				{ cause: error }
			);
		}

		throw new Error(
			`Cannot find module ${id}. ` +
				`npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). ` +
				'Please try `npm i` again after removing both package-lock.json and node_modules directory.',
			{ cause: error }
		);
	}
};

const { parse, parseAsync, xxhashBase64Url, xxhashBase36, xxhashBase16 } = requireWithFriendlyError(
	existsSync(path.join(__dirname, localName)) ? localName : `@rollup/rollup-${packageBase}`
);

function getPackageBase() {
	const imported = bindingsByPlatformAndArch[platform]?.[arch];
	if (!imported) {
		throwUnsupportedError(false);
	}
	if ('musl' in imported && isMusl()) {

View on GitHub (pinned to ddc4ffab62)

Solutions

  1. Delete `node_modules` and `package-lock.json`, then run `npm i` again.
  2. If it persists, install `@rollup/wasm-node` as a fallback.
  3. Upgrade npm to a version that has the optional-deps fix (npm 8+).
  4. Ensure install and run happen on the same platform/arch (or use the WASM build for portability).
Defensive patterns

Strategy: retry

Validate before calling

// Preflight: ensure the platform-specific optional dep is resolvable.
const { platform, arch } = require('node:process');
function nativeBindingResolvable() {
  try {
    require.resolve(`@rollup/rollup-${getPackageBase()}`);
    return true;
  } catch { return false; }
}
if (!nativeBindingResolvable()) {
  throw new Error('Native Rollup binary missing — clean-reinstall node_modules + package-lock.json');
}

Try / catch

// Reinstall on failure, then fall back to WASM.
const { execSync } = require('node:child_process');
try { rollupApi = require('rollup'); }
catch (err) {
  if (/npm has a bug related to optional dependencies/.test(err.message)) {
    execSync('rm -rf node_modules package-lock.json && npm i', { stdio: 'inherit' });
    rollupApi = require('@rollup/wasm-node');
  } else throw err;
}

Prevention

When it happens

Trigger: After `npm install`, `require('@rollup/rollup-<platform-arch>')` fails because the optional dep was not installed; happens with lockfile drift, npm 7 bugs, or installing on one platform and running on another.

Common situations: Broken CI caches, switching OS/arch between install and run, npm lockfile version mismatches, corrupted `node_modules`.

Related errors


AI-assisted analysis of rollup/rollup@ddc4ffab62 (2026-08-03). Data as JSON: /data/errors/aaffc4b56bf57f28.json. Report an issue: GitHub.