{"record":{"id":"a4f96b966c65e859","repo":"nikivdev/code","slug":"bun-npx-or-npm-is-required-to-run-wrangler","errorCode":null,"errorMessage":"bun, npx, or npm is required to run wrangler","messagePattern":"bun, npx, or npm is required to run wrangler","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/docs.rs","lineNumber":698,"sourceCode":"\nfn attach_pages_domain(hub_root: &Path, project: &str, domain: &str) -> Result<()> {\n    println!(\"Attaching custom domain {domain} to {project}...\");\n    let mut cmd = if which(\"bun\").is_ok() {\n        let mut cmd = Command::new(\"bun\");\n        cmd.args([\"x\", \"wrangler\", \"pages\", \"domain\", \"add\", project, domain]);\n        cmd\n    } else if which(\"npx\").is_ok() {\n        let mut cmd = Command::new(\"npx\");\n        cmd.args([\"wrangler\", \"pages\", \"domain\", \"add\", project, domain]);\n        cmd\n    } else if which(\"npm\").is_ok() {\n        let mut cmd = Command::new(\"npm\");\n        cmd.args([\n            \"exec\", \"wrangler\", \"--\", \"pages\", \"domain\", \"add\", project, domain,\n        ]);\n        cmd\n    } else {\n        bail!(\"bun, npx, or npm is required to run wrangler\");\n    };\n    let status = cmd\n        .current_dir(hub_root)\n        .stdin(std::process::Stdio::inherit())\n        .stdout(std::process::Stdio::inherit())\n        .stderr(std::process::Stdio::inherit())\n        .status()\n        .context(\"failed to run wrangler pages domain add\")?;\n    if !status.success() {\n        bail!(\"wrangler pages domain add failed\");\n    }\n    Ok(())\n}\n\nfn prompt_line(message: &str, default: Option<&str>) -> Result<String> {\n    if let Some(default) = default {\n        print!(\"{message} [{default}]: \");\n    } else {","sourceCodeStart":680,"sourceCodeEnd":716,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/docs.rs#L680-L716","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","solutions":["Install Node.js (provides npm and npx) or bun and ensure it is on PATH","If only pnpm/yarn exist, install npm-compatible tooling or use corepack to provide npx","Fix PATH in the invoking environment (CI env, sudo secure_path, wrapper script)","Pre-flight check: `which bun || which npx || which npm`"],"exampleFix":"// before\n$ mytool docs hub deploy --domain docs.example.com\nError: bun, npx, or npm is required to run wrangler\n// after\n$ apt-get install -y nodejs npm   # or install bun\n$ mytool docs hub deploy --domain docs.example.com","handlingStrategy":"validation","validationCode":"let has_runner = [\"bun\", \"npx\", \"npm\"].iter().any(|c| which::which(c).is_ok());\nif !has_runner {\n    eprintln!(\"install Node.js or bun to deploy with wrangler\");\n    return;\n}\ndeploy_docs_hub(&opts)?;","typeGuard":null,"tryCatchPattern":"match deploy_docs_hub(&opts) {\n    Err(e) if e.to_string().contains(\"required to run wrangler\") => {\n        eprintln!(\"install bun or Node.js (npm/npx) before deploying with a custom domain\");\n    }\n    Err(e) => return Err(e),\n    Ok(()) => {}\n}","preventionTips":["Install Node.js/bun in CI images used for docs hub deployment","Check `which bun || which npx || which npm` at the top of deploy scripts","Fix PATH under sudo/cron (secure_path, explicit PATH export)","Note pnpm/yarn-only installs don't satisfy this check — include npm-compatible tooling"],"tags":["rust","missing-dependency","wrangler","cloudflare","path"],"backgroundTag":"missing-required-command","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}