ruvnet/ruflo · warning · Error

Installation failed

Error message

Installation failed

What it means

Generic fallback thrown by autoInstallPackage when `npm install` (run via spawnSync with shell:false) exits with a non-zero status AND produced no stderr output. It is the last-resort message; when npm prints an error the actual stderr text is used instead. The surrounding try/catch swallows it and the function returns false, so callers see a boolean, not the throw.

Source

Thrown at v3/@claude-flow/cli/src/mcp-tools/auto-install.ts:73

    return false;
  }
  installAttempts.add(packageName);

  try {
    if (!silent) {
      console.error(`[claude-flow] Auto-installing ${packageName}...`);
    }

    // Use spawn with array args to prevent shell injection
    const args = ['install', packageName, save ? '--save' : '--no-save'];
    const result = spawnSync('npm', args, {
      stdio: silent ? 'pipe' : ['pipe', 'pipe', 'pipe'],
      timeout,
      shell: false, // Explicitly disable shell
    });

    if (result.status !== 0) {
      throw new Error(result.stderr?.toString() || 'Installation failed');
    }

    if (!silent) {
      console.error(`[claude-flow] Successfully installed ${packageName}`);
    }
    return true;
  } catch (error) {
    if (!silent) {
      console.error(`[claude-flow] Failed to auto-install ${packageName}: ${error}`);
    }
    return false;
  }
}

/**
 * Try to import a package, auto-install if not found, and retry
 *
 * @param packageName - npm package name

View on GitHub (pinned to 6b01dc5a68)

Solutions

  1. Run `npm install <package>` manually in the project to see the real npm error output (auto-install hides it).
  2. Confirm npm is installed and on PATH (`npm --version`); the tool shells out to `npm`.
  3. Check network/proxy/registry configuration (.npmrc, https_proxy) if the package genuinely exists.
  4. Pre-install the optional dependency as a real dependency so auto-install is never triggered.
  5. Note the once-per-session dedupe: if the first attempt failed, restart the process or clear state before retrying.

Example fix

// before: rely on auto-install at runtime
await autoInstallPackage('some-optional-pkg')
// after: declare it as a real dependency
// package.json: "dependencies": { "some-optional-pkg": "^1.0.0" }
Defensive patterns

Strategy: fallback

Validate before calling

async function safeRequire(pkg) {
  try { return await import(pkg); }
  catch {
    const ok = await autoInstallPackage(pkg, { silent: true });
    if (!ok) return null;  // caller degrades gracefully
    try { return await import(pkg); } catch { return null; }
  }
}

Try / catch

const installed = await autoInstallPackage(pkg, { timeout: 60000 });
if (!installed) {
  // autoInstallPackage already swallowed the throw and returned false;
  // surface a clear message rather than relying on the generic 'Installation failed'.
  console.error(`Optional dependency '${pkg}' unavailable; install manually or check npm.`);
}

Prevention

When it happens

Trigger: npm exits non-zero with empty stderr: package does not exist in the registry, npm is offline, npm itself is not on PATH (spawnSync returns status null and ENOENT surfaces elsewhere), registry auth rejected with no stderr, or a transient network failure. Only one install attempt per package per session is allowed, so a second call silently returns false.

Common situations: Air-gapped or proxy-restricted environments where npm cannot reach the registry; a typo'd or unpublished optional dependency; npm not installed in the container; a corporate npm registry requiring auth that was not configured; the package name passed validation but 404s.

Related errors


AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12). Data as JSON: /api/errors/bc8a3fcf4bc8e86d. Report an issue: GitHub.