{"record":{"id":"95616eed89550e64","repo":"n8n-io/n8n","slug":"npm-pack-failed-npmresult-stderr-tostring","errorCode":null,"errorMessage":"npm pack failed: ${npmResult.stderr?.toString()}","messagePattern":"npm pack failed: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/scan-community-package/scanner/scanner.mjs","lineNumber":89,"sourceCode":"\t\t\t// Handle scoped packages without version\n\t\t\treturn { packageName: packageSpec, version: null };\n\t\t}\n\t}\n\t// Handle regular packages\n\tconst parts = packageSpec.split('@');\n\treturn { packageName: parts[0], version: parts[1] || null };\n};\n\nconst downloadAndExtractPackage = async (packageName, version) => {\n\ttry {\n\t\t// Download the tarball using safe arguments\n\t\tconst npmResult = spawnSync('npm', ['-q', 'pack', `${packageName}@${version}`], {\n\t\t\tcwd: TEMP_DIR,\n\t\t\tstdio: 'pipe',\n\t\t\tshell: process.platform === 'win32',\n\t\t});\n\t\tif (npmResult.status !== 0) {\n\t\t\tthrow new Error(`npm pack failed: ${npmResult.stderr?.toString()}`);\n\t\t}\n\t\tconst tarballName = fs.readdirSync(TEMP_DIR).find((file) => file.endsWith('.tgz'));\n\t\tif (!tarballName) {\n\t\t\tthrow new Error('Tarball not found');\n\t\t}\n\n\t\t// Unpack the tarball\n\t\tconst packageDir = safeJoinPath(TEMP_DIR, `${packageName}-${version}`);\n\t\tfs.mkdirSync(packageDir, { recursive: true });\n\t\tconst tarResult = spawnSync(\n\t\t\t'tar',\n\t\t\t['-xzf', tarballName, '-C', packageDir, '--strip-components=1'],\n\t\t\t{\n\t\t\t\tcwd: TEMP_DIR,\n\t\t\t\tstdio: 'pipe',\n\t\t\t\tshell: process.platform === 'win32',\n\t\t\t},\n\t\t);","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/scan-community-package/scanner/scanner.mjs#L71-L107","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the embedded stderr in the error message - it usually states 'version not found', 'E404', or 'ENOTFOUND' directly.","Verify the package exists: `npm view ${packageName}@${version}` in the same environment and registry.","For private scopes, set NPM_CONFIG_REGISTRY and an auth token (//registry/.../:_authToken) in the environment before running the scanner.","Confirm `npm --version` works in PATH and that the scanner process has network egress to the registry."],"exampleFix":"# before - scanner fails with 'npm pack failed: ...'\nnpm config get registry\n\n# after - configure auth for a private scope and retry\nnpm config set @myscope:registry https://npm.pkg.github.com\nexport NODE_AUTH_TOKEN=ghp_xxx\n# re-run the scanner","handlingStrategy":"try-catch","validationCode":"import { execFileSync } from 'node:child_process';\n\nfunction npmPackWorks(): boolean {\n  try {\n    execFileSync('npm', ['--version'], { stdio: 'pipe', shell: process.platform === 'win32' });\n    return true;\n  } catch {\n    return false;\n  }\n}\n\nif (!npmPackWorks()) {\n  throw new Error('npm is not available on PATH; scanner cannot fetch packages');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await downloadAndExtractPackage(packageName, version);\n} catch (e) {\n  const msg = (e as Error).message;\n  if (msg.startsWith('npm pack failed:')) {\n    // Inspect embedded stderr - 404 vs ENOTFOUND vs auth need different fixes.\n    if (msg.includes('E404')) throw new Error(`Package not found: ${packageName}@${version}`);\n    if (msg.includes('ENEEDAUTH')) throw new Error(`Auth required for ${packageName}; set NPM_TOKEN`);\n    throw new Error(`npm pack unreachable: ${msg}`);\n  }\n  throw e;\n}","preventionTips":["Pre-flight `npm view ${packageName}@${version}` to confirm the package exists on the configured registry before scanning.","Set NPM_CONFIG_REGISTRY and scope-specific auth in the scanner environment.","Confirm `npm --version` succeeds in the scanner's PATH.","Run scans in an environment with network egress to the registry."],"tags":["network","npm","scanner","registry"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}