zed-industries/zed · error
failed to run node --version. stdout: {}, stderr: {}
Error message
failed to run node --version. stdout: {}, stderr: {} What it means
SystemNodeRuntime::new sanity-checks a system-provided node binary by executing `node --version`. If the process runs but exits non-zero, the failure bails with the captured stdout and stderr. (A failure even to spawn the process produces the earlier `running node from {path}` context instead.)
Source
Thrown at crates/node_runtime/src/node_runtime.rs:868
}
#[derive(Debug, Clone)]
pub struct SystemNodeRuntime {
node: PathBuf,
npm: PathBuf,
scratch_dir: PathBuf,
}
impl SystemNodeRuntime {
const MIN_VERSION: semver::Version = Version::new(22, 0, 0);
async fn new(node: PathBuf, npm: PathBuf) -> Result<Self> {
let output = util::command::new_command(&node)
.arg("--version")
.output()
.await
.with_context(|| format!("running node from {:?}", node))?;
if !output.status.success() {
anyhow::bail!(
"failed to run node --version. stdout: {}, stderr: {}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr),
);
}
let version_str = String::from_utf8_lossy(&output.stdout);
let version = semver::Version::parse(version_str.trim().trim_start_matches('v'))?;
if version < Self::MIN_VERSION {
anyhow::bail!(
"node at {} is too old. want: {}, got: {}",
node.to_string_lossy(),
Self::MIN_VERSION,
version
)
}
let scratch_dir = paths::data_dir().join("node");
fs::create_dir(&scratch_dir).await.ok();View on GitHub (pinned to 9d272b0363)
Solutions
- Run `node --version` yourself with the same PATH Zed uses — reproduce and read the stderr
- Reinstall Node (or fix the version manager shims: `nvm reinstall <version>`, `volta install node`)
- Clear quarantine on a copied binary: xattr -d com.apple.quarantine $(which node)
- Point Zed at a healthy node via PATH, or remove system node so the bundled runtime is used
Defensive patterns
Strategy: fallback
Validate before calling
async fn node_runs(node: &Path) -> bool {
util::command::new_command(node)
.arg("--version")
.output()
.await
.map(|o| o.status.success())
.unwrap_or(false)
} Try / catch
match SystemNodeRuntime::new(node, npm).await {
Err(e) if e.to_string().contains("node --version") => {
// binary is broken: fall back to the bundled downloader
NodeRuntime::install_if_needed(&http).await?
}
r => r?,
} Prevention
- Verify `node --version` succeeds in the exact environment (PATH, shell, sandbox) before opting into the system runtime
- Reinstall via the version manager rather than copying binaries around
- On macOS, clear quarantine attributes from manually installed node binaries
When it happens
Trigger: The node binary found on PATH executes but errors: a corrupted or wrong-architecture binary that dies on startup, a wrapper/shim (nvm, volta, mise) whose underlying install is broken, or a sandbox/AV blocking the exec so it exits with an error code.
Common situations: Half-finished nvm/volta installs; macOS quarantine attributes on a manually copied node; Docker images where node is a broken symlink shim; SELinux/AppArmor denials.
Related errors
- node at {} is too old. want: {}, got: {}
- git blame process failed: {stderr}
- Default prettier is not installed and cannot be started
- Cannot start default prettier due to its installation failur
- {}
AI-assisted analysis of zed-industries/zed@9d272b0363 (2026-08-20).
Data as JSON: /api/errors/78baa986f74267da.
Report an issue: GitHub.