n8n-io/n8n · error · Error

npm pack failed: ${npmResult.stderr?.toString()}

Error message

npm pack failed: ${npmResult.stderr?.toString()}

What it means

Thrown by downloadAndExtractPackage when `npm pack` exits non-zero while fetching a package tarball into TEMP_DIR. The message embeds npm's stderr so the underlying registry/auth/network failure is visible. This is the entry-point failure for the whole scan pipeline: no tarball means no extraction, no source lookup, no lint.

Source

Thrown at packages/@n8n/scan-community-package/scanner/scanner.mjs:89

			// Handle scoped packages without version
			return { packageName: packageSpec, version: null };
		}
	}
	// Handle regular packages
	const parts = packageSpec.split('@');
	return { packageName: parts[0], version: parts[1] || null };
};

const downloadAndExtractPackage = async (packageName, version) => {
	try {
		// Download the tarball using safe arguments
		const npmResult = spawnSync('npm', ['-q', 'pack', `${packageName}@${version}`], {
			cwd: TEMP_DIR,
			stdio: 'pipe',
			shell: process.platform === 'win32',
		});
		if (npmResult.status !== 0) {
			throw new Error(`npm pack failed: ${npmResult.stderr?.toString()}`);
		}
		const tarballName = fs.readdirSync(TEMP_DIR).find((file) => file.endsWith('.tgz'));
		if (!tarballName) {
			throw new Error('Tarball not found');
		}

		// Unpack the tarball
		const packageDir = safeJoinPath(TEMP_DIR, `${packageName}-${version}`);
		fs.mkdirSync(packageDir, { recursive: true });
		const tarResult = spawnSync(
			'tar',
			['-xzf', tarballName, '-C', packageDir, '--strip-components=1'],
			{
				cwd: TEMP_DIR,
				stdio: 'pipe',
				shell: process.platform === 'win32',
			},
		);

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Check the embedded stderr in the error message - it usually states 'version not found', 'E404', or 'ENOTFOUND' directly.
  2. Verify the package exists: `npm view ${packageName}@${version}` in the same environment and registry.
  3. For private scopes, set NPM_CONFIG_REGISTRY and an auth token (//registry/.../:_authToken) in the environment before running the scanner.
  4. Confirm `npm --version` works in PATH and that the scanner process has network egress to the registry.

Example fix

# before - scanner fails with 'npm pack failed: ...'
npm config get registry

# after - configure auth for a private scope and retry
npm config set @myscope:registry https://npm.pkg.github.com
export NODE_AUTH_TOKEN=ghp_xxx
# re-run the scanner
Defensive patterns

Strategy: try-catch

Validate before calling

import { execFileSync } from 'node:child_process';

function npmPackWorks(): boolean {
  try {
    execFileSync('npm', ['--version'], { stdio: 'pipe', shell: process.platform === 'win32' });
    return true;
  } catch {
    return false;
  }
}

if (!npmPackWorks()) {
  throw new Error('npm is not available on PATH; scanner cannot fetch packages');
}

Try / catch

try {
  await downloadAndExtractPackage(packageName, version);
} catch (e) {
  const msg = (e as Error).message;
  if (msg.startsWith('npm pack failed:')) {
    // Inspect embedded stderr - 404 vs ENOTFOUND vs auth need different fixes.
    if (msg.includes('E404')) throw new Error(`Package not found: ${packageName}@${version}`);
    if (msg.includes('ENEEDAUTH')) throw new Error(`Auth required for ${packageName}; set NPM_TOKEN`);
    throw new Error(`npm pack unreachable: ${msg}`);
  }
  throw e;
}

Prevention

When it happens

Trigger: spawnSync('npm', ['-q', 'pack', `${packageName}@${version}`]) returns status !== 0 because the package/version does not exist on the configured registry, the registry is unreachable, npm auth is missing for a private scope, or npm itself is not on PATH.

Common situations: Private scoped package (@scope/name) scanned without NPM_TOKEN/registry auth; offline environment; corporate npm proxy that blocks `npm pack`; typo in version that resolves to nothing; npm not installed in the scanner environment.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/95616eed89550e64. Report an issue: GitHub.