nikivdev/code · error · anyhow::Error

bun, npx, or npm is required to run wrangler

Error message

bun, npx, or npm is required to run wrangler

What it means

attach_pages_domain needs the wrangler CLI (Cloudflare Pages) to add a custom domain, invoked via bun, npx, or npm exec. If none of the three runners is found on PATH it bails before attempting the wrangler call.

Source

Thrown at src/docs.rs:698

fn attach_pages_domain(hub_root: &Path, project: &str, domain: &str) -> Result<()> {
    println!("Attaching custom domain {domain} to {project}...");
    let mut cmd = if which("bun").is_ok() {
        let mut cmd = Command::new("bun");
        cmd.args(["x", "wrangler", "pages", "domain", "add", project, domain]);
        cmd
    } else if which("npx").is_ok() {
        let mut cmd = Command::new("npx");
        cmd.args(["wrangler", "pages", "domain", "add", project, domain]);
        cmd
    } else if which("npm").is_ok() {
        let mut cmd = Command::new("npm");
        cmd.args([
            "exec", "wrangler", "--", "pages", "domain", "add", project, domain,
        ]);
        cmd
    } else {
        bail!("bun, npx, or npm is required to run wrangler");
    };
    let status = cmd
        .current_dir(hub_root)
        .stdin(std::process::Stdio::inherit())
        .stdout(std::process::Stdio::inherit())
        .stderr(std::process::Stdio::inherit())
        .status()
        .context("failed to run wrangler pages domain add")?;
    if !status.success() {
        bail!("wrangler pages domain add failed");
    }
    Ok(())
}

fn prompt_line(message: &str, default: Option<&str>) -> Result<String> {
    if let Some(default) = default {
        print!("{message} [{default}]: ");
    } else {

View on GitHub (pinned to a747e741ae)

Solutions

  1. Install Node.js (provides npm and npx) or bun and ensure it is on PATH
  2. If only pnpm/yarn exist, install npm-compatible tooling or use corepack to provide npx
  3. Fix PATH in the invoking environment (CI env, sudo secure_path, wrapper script)
  4. Pre-flight check: `which bun || which npx || which npm`

Example fix

// before
$ mytool docs hub deploy --domain docs.example.com
Error: bun, npx, or npm is required to run wrangler
// after
$ apt-get install -y nodejs npm   # or install bun
$ mytool docs hub deploy --domain docs.example.com
Defensive patterns

Strategy: validation

Validate before calling

let has_runner = ["bun", "npx", "npm"].iter().any(|c| which::which(c).is_ok());
if !has_runner {
    eprintln!("install Node.js or bun to deploy with wrangler");
    return;
}
deploy_docs_hub(&opts)?;

Try / catch

match deploy_docs_hub(&opts) {
    Err(e) if e.to_string().contains("required to run wrangler") => {
        eprintln!("install bun or Node.js (npm/npx) before deploying with a custom domain");
    }
    Err(e) => return Err(e),
    Ok(()) => {}
}

Prevention

When it happens

Trigger: Calling deploy_docs_hub with a custom domain on a host without bun, npx, or npm; or where Node tooling exists but is not on the PATH of the invoking process.

Common situations: Deploying from CI images without Node; bare servers; PATH stripped under sudo/cron; user only has pnpm/yarn installed (neither bun, npx, nor npm present).

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/a4f96b966c65e859. Report an issue: GitHub.