davila7/claude-code-templates · error · anyhow::Error

failed to launch Node CLI: {e}. Is Node.js installed?

Error message

failed to launch Node CLI: {e}. Is Node.js installed?

What it means

Rust CLI error when spawning the Node CLI subprocess fails: Command::status() returns Err, meaning the node executable could not be launched at all (not that the CLI errored). The message suggests Node.js is missing or not on PATH.

Source

Thrown at cli-rust/src/commands/delegate.rs:19

//! Delegation to the existing Node.js CLI for features not yet ported natively
//! (dashboards, sandbox, global agents, stats, health-check, interactive setup).
//!
//! Resolution order for the Node entry point:
//! 1. `CCT_NODE_BIN` env var — path to `create-claude-config.js` (run with
//!    `node`) or an executable to invoke directly. Used for local testing.
//! 2. Fallback: `npx -y claude-code-templates@latest <args>`.
//!
//! The original process args (everything after the binary name) are forwarded
//! verbatim with inherited stdio, so the delegated command behaves identically.

use anyhow::{anyhow, Result};
use std::process::Command;

pub fn delegate_to_node(forwarded_args: &[String]) -> Result<i32> {
    let mut command = build_command(forwarded_args)?;
    let status = command
        .status()
        .map_err(|e| anyhow!("failed to launch Node CLI: {e}. Is Node.js installed?"))?;
    // Preserve the child's termination semantics: a normal exit code, or for a
    // signal-killed child on Unix, the shell convention 128 + signal.
    let code = status.code().unwrap_or_else(|| {
        #[cfg(unix)]
        {
            use std::os::unix::process::ExitStatusExt;
            status.signal().map(|s| 128 + s).unwrap_or(1)
        }
        #[cfg(not(unix))]
        {
            1
        }
    });
    Ok(code)
}

fn build_command(forwarded_args: &[String]) -> Result<Command> {
    if let Ok(node_bin) = std::env::var("CCT_NODE_BIN") {

View on GitHub (pinned to a0851ed10c)

Solutions

  1. Verify node is installed and on PATH: `node --version` from the same environment
  2. Use an absolute node path or fix PATH (nvm use, or add node to the invoking environment's PATH)
  3. Reinstall Node.js (>= required version) if the binary is broken
  4. On Linux/macOS check execute permissions and ulimit on processes

Example fix

# before
export PATH=/usr/local/bin:/usr/bin:/bin   # node installed via nvm, not found
# after
export PATH="$HOME/.nvm/versions/node/v22.11.0/bin:$PATH"
cli-rust --agent frontend-developer
Defensive patterns

Strategy: validation

Validate before calling

use std::process::Command;
fn node_available() -> bool {
    Command::new("node").arg("--version").output().is_ok()
}
// call before delegate_to_node; fall back to npx or a bundled binary if false

Try / catch

match cmd.status() {
    Ok(status) => Ok(status.code().unwrap_or(1)),
    Err(e) if e.kind() == std::io::ErrorKind::NotFound =>
        suggest_install_node(),
    Err(e) => Err(anyhow!("failed to launch Node CLI: {e}")),
}

Prevention

When it happens

Trigger: Running the Rust wrapper (e.g. `cli-rust --agent x`) where `node` is not found (ENOENT), not executable (EACCES), or process limits prevent spawning.

Common situations: Node not installed or removed; PATH differs when invoked from a GUI/launcher/systemd vs a shell; nvm-managed node not on PATH in non-login shells; Windows without node.exe in PATH.

Related errors


AI-assisted analysis of davila7/claude-code-templates@a0851ed10c (2026-08-28). Data as JSON: /api/errors/080226d4d91988f4. Report an issue: GitHub.