nikivdev/code · error · anyhow::Error

docs hub dev server exited with error

Error message

docs hub dev server exited with error

What it means

After spawning the docs hub dev server as a child process, run_docs_hub_dev waits on it and bails if the exit status is not success. This means the dev server process was started but terminated with a non-zero exit code — the crash happened inside bun/npm/Next.js, not in this library.

Source

Thrown at src/docs.rs:597

        bail!("bun or npm is required to run docs hub dev server");
    };

    let mut child = cmd
        .current_dir(hub_root)
        .stdout(std::process::Stdio::inherit())
        .stderr(std::process::Stdio::inherit())
        .spawn()
        .context("failed to start docs hub dev server")?;

    if !no_open {
        let url = format!("http://{}:{}", host, port);
        wait_for_port(host, port, std::time::Duration::from_secs(10));
        open_in_browser(&url);
    }

    let status = child.wait().context("failed to wait on docs hub")?;
    if !status.success() {
        bail!("docs hub dev server exited with error");
    }
    Ok(())
}

fn start_docs_hub_daemon(hub_root: &Path, host: &str, port: u16) -> Result<()> {
    let mut cmd = if which("bun").is_ok() {
        let port_arg = port.to_string();
        let host_arg = host.to_string();
        let mut cmd = Command::new("bun");
        cmd.args([
            "run",
            "dev",
            "--",
            "--port",
            &port_arg,
            "--hostname",
            &host_arg,
        ]);

View on GitHub (pinned to a747e741ae)

Solutions

  1. Read the child's stderr/stdout (they are inherited) for the real failure — e.g. EADDRINUSE — and free the port (`lsof -i :4410`, kill the stale process, or pass a different --port)
  2. Run `bun install` (or `npm install`) in the hub root to fix missing/broken dependencies, then retry
  3. Recreate the hub directory to get a clean template copy if the app itself is corrupted
  4. If the non-zero status was just Ctrl-C, treat it as expected and re-run when needed

Example fix

// before
$ mytool docs hub dev
Error: docs hub dev server exited with error
  (stderr: Error: listen EADDRINUSE: 4410)
// after
$ lsof -ti :4410 | xargs kill
$ mytool docs hub dev --port 4411
Defensive patterns

Strategy: retry

Validate before calling

// pre-check the port before starting the dev server
fn port_free(host: &str, port: u16) -> bool {
    std::net::TcpListener::bind((host, port)).is_ok()
}
if !port_free("127.0.0.1", 4410) {
    eprintln!("port 4410 in use — stop the old hub or pass a different --port");
    return;
}

Try / catch

match run_docs_hub(&opts) {
    Err(e) if e.to_string().contains("docs hub dev server exited with error") => {
        eprintln!("dev server crashed; inspect inherited stderr (port in use? missing deps?) and retry");
        // retry once after bun install
        let _ = std::process::Command::new("bun").arg("install").current_dir(&hub_root).status();
    }
    Err(e) => return Err(e),
    Ok(()) => {}
}

Prevention

When it happens

Trigger: Calling run_docs_hub when the spawned `bun dev` / `npm run dev` process fails at runtime: port already bound by another process, missing node_modules or broken install, syntax/config error in the hub app, or the user presses Ctrl-C (SIGINT yields non-success status).

Common situations: Port 4410 already in use by a previous hub instance; dependencies never installed (`bun install` skipped or failed silently); corrupted node_modules after an upgrade; terminating the command with Ctrl-C; Node version too old for the hub's framework.

Related errors


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