{"record":{"id":"20c0ee72590295b8","repo":"ruvnet/ruflo","slug":"result-stderr-tostring-installation-faile","errorCode":null,"errorMessage":"${result.stderr?.toString() || 'Installation failed'}","messagePattern":"\\$\\{result\\.stderr\\?\\.toString\\(\\) \\|\\| 'Installation failed'\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/mcp-tools/auto-install.ts","lineNumber":73,"sourceCode":"    return false;\n  }\n  installAttempts.add(packageName);\n\n  try {\n    if (!silent) {\n      console.error(`[claude-flow] Auto-installing ${packageName}...`);\n    }\n\n    // Use spawn with array args to prevent shell injection\n    const args = ['install', packageName, save ? '--save' : '--no-save'];\n    const result = spawnSync('npm', args, {\n      stdio: silent ? 'pipe' : ['pipe', 'pipe', 'pipe'],\n      timeout,\n      shell: false, // Explicitly disable shell\n    });\n\n    if (result.status !== 0) {\n      throw new Error(result.stderr?.toString() || 'Installation failed');\n    }\n\n    if (!silent) {\n      console.error(`[claude-flow] Successfully installed ${packageName}`);\n    }\n    return true;\n  } catch (error) {\n    if (!silent) {\n      console.error(`[claude-flow] Failed to auto-install ${packageName}: ${error}`);\n    }\n    return false;\n  }\n}\n\n/**\n * Try to import a package, auto-install if not found, and retry\n *\n * @param packageName - npm package name","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/mcp-tools/auto-install.ts#L55-L91","documentation":"Produced by ensurePackageInstalled() in auto-install.ts:73 when `spawnSync('npm', ['install', pkg, ...])` exits non-zero. The thrown message is npm's stderr (or 'Installation failed' when stderr is empty). The function then catches this error, logs '[claude-flow] Failed to auto-install <pkg>: <error>' unless silent, and returns false — so callers usually see a degraded/missing-package result rather than the throw itself.","triggerScenarios":"Any npm install failure inside the auto-install path: package or version not found (E404), registry unreachable (ENOTFOUND, EAI_AGAIN, ETIMEDOUT), private scoped package without credentials (E401/E403), corporate proxy or air-gapped network blocking registry.npmjs.org, corrupted npm cache, or the spawnSync timeout elapsing.","commonSituations":"CI runners without network egress; private @scope packages needing an .npmrc token; a typo'd optional dependency name; Node/npm version mismatch; environments where 'npm' is not on PATH for the MCP server process (ENOENT surfaces as 'Installation failed').","solutions":["Run `npm install <package>` manually in the project root — npm's full diagnostic output shows the real cause (404 vs auth vs network)","Fix environment: add registry/token to .npmrc, set HTTP(S)_PROXY, or run `npm cache clean --force` for cache corruption","Pre-install optional dependencies in your image/Dockerfile so the auto-install path never runs","Pin an existing version if the failure is E404 on a tag that does not exist"],"exampleFix":"# before: relying on runtime auto-install in CI\n# (auto-install fails offline -> tool degrades)\n\n# after: pre-install in the image\nRUN npm install --save <optional-package>\n# app then resolves it locally; auto-install is skipped","handlingStrategy":"fallback","validationCode":"import { createRequire } from 'node:module';\nconst require = createRequire(import.meta.url);\nfunction resolvesLocally(pkg: string): boolean {\n  try { require.resolve(pkg); return true; } catch { return false; }\n}\n// pre-install path: if not resolvable, preinstall instead of relying on auto-install\nif (!resolvesLocally(pkg) && !canReachRegistry()) {\n  console.error('pre-installing optional deps');\n  await exec('npm install');\n}","typeGuard":null,"tryCatchPattern":"// auto-install already swallows the throw and returns false; handle that contract:\nconst ok = await ensurePackageInstalled(pkg);\nif (!ok) {\n  // fall back: degrade the feature, or surface manual install instructions\n  return { degraded: true, hint: `npm install ${pkg} manually to enable this feature` };\n}","preventionTips":["Pre-install optional dependencies in your Dockerfile/CI image so the auto-install path never runs","Configure .npmrc (registry, token, proxy) in the environment where the MCP server runs","Manually `npm install <pkg>` once to see npm's real error before debugging the tool"],"tags":["npm","installation","network","dependencies","tooling"],"backgroundTag":"npm-install-failed","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}