{"record":{"id":"75dbafce6675823b","repo":"jackwener/OpenCLI","slug":"npm-install-failed-in-dir-geterrormessage-er","errorCode":null,"errorMessage":"npm install failed in ${dir}: ${getErrorMessage(err)}","messagePattern":"npm install failed in (.+?): (.+?)","errorType":"exception","errorClass":"PluginError","httpStatus":null,"severity":"error","filePath":"src/plugin.ts","lineNumber":581,"sourceCode":"  const pkgJsonPath = path.join(dir, 'package.json');\n  if (!fs.existsSync(pkgJsonPath)) return;\n\n  try {\n    // --ignore-scripts is a security boundary, not an optimization: the plugin\n    // repo was just cloned from an untrusted third-party Git URL, and without\n    // this flag npm would execute preinstall/install/postinstall lifecycle\n    // scripts declared by the plugin (and every transitive dep) with the user's\n    // privileges at install time. Adapter plugins don't need lifecycle scripts\n    // to work — the adapter code is loaded later by the discovery path — so we\n    // deny that extra execution vector unconditionally. See issue #1753.\n    execFileSync('npm', ['install', '--omit=dev', '--ignore-scripts'], {\n      cwd: dir,\n      encoding: 'utf-8',\n      stdio: ['pipe', 'pipe', 'pipe'],\n      ...(isWindows && { shell: true }),\n    });\n  } catch (err) {\n    throw new PluginError(`npm install failed in ${dir}: ${getErrorMessage(err)}`, 'Check your network connection and npm configuration.');\n  }\n}\n\nfunction finalizePluginRuntime(pluginDir: string): void {\n  // Symlink host opencli so TS plugins resolve '@jackwener/opencli/registry'\n  // against the running host, not a stale npm-published version.\n  linkHostOpencli(pluginDir);\n\n  // Transpile .ts → .js via esbuild (production node can't load .ts directly).\n  transpilePluginTs(pluginDir);\n}\n\n/**\n * Shared post-install lifecycle for standalone plugins.\n */\nfunction postInstallLifecycle(pluginDir: string): void {\n  installDependencies(pluginDir);\n  finalizePluginRuntime(pluginDir);","sourceCodeStart":563,"sourceCodeEnd":599,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/src/plugin.ts#L563-L599","documentation":"installDependencies runs `npm install --omit=dev --ignore-scripts` inside the plugin (or monorepo root) directory. If npm exits non-zero, the error is wrapped in a PluginError pointing at the failing directory. opencli throws this because plugin dependencies could not be installed, so the plugin would fail to load its imports.","triggerScenarios":"installPlugin/installLocalPlugin/updatePlugin reaching postInstallLifecycle or postInstallMonorepoLifecycle when the plugin has a package.json: npm registry unreachable, invalid package.json dependency spec, version conflicts, private registry auth missing, corrupted package-lock.json, or npm missing/broken on Windows shell.","commonSituations":"Corporate proxy or offline npm; plugin depends on an unpublished or renamed package; bad .npmrc (registry URL, auth token expired); ERESOLVE peer-dependency conflicts; out-of-date npm.","solutions":["Reproduce manually: `cd <dir> && npm install --omit=dev --ignore-scripts` to see the real npm error.","Check network/registry access and .npmrc configuration (registry URL, auth tokens, proxy).","Fix the plugin's package.json dependency versions (pin existing, published versions).","Delete node_modules and package-lock.json in the plugin dir and retry.","Update npm (`npm install -g npm`) if the npm error indicates an npm bug."],"exampleFix":"// before (package.json)\n\"dependencies\": { \"undici\": \"^99.0.0\" } // version doesn't exist\n// after\n\"dependencies\": { \"undici\": \"^6.0.0\" }","handlingStrategy":"retry","validationCode":"import { execFileSync } from 'node:child_process';\nfunction npmReachable() {\n  try {\n    execFileSync('npm', ['ping'], { stdio: 'pipe' });\n    return true;\n  } catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  installPlugin(source);\n} catch (err) {\n  if (err instanceof PluginError && err.message.startsWith('npm install failed')) {\n    // inspect npm config/registry, fix deps, then retry once\n  } else throw err;\n}","preventionTips":["Verify `npm ping` / registry access and .npmrc auth before installing plugins.","Keep plugin package.json dependencies pinned to published versions.","Run `npm install --omit=dev --ignore-scripts` in the plugin repo during CI to catch issues early.","Update npm regularly; clear a corrupted package-lock.json when versions shift."],"tags":["npm","network","dependencies","plugin-install"],"backgroundTag":"npm-install-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}