rust-lang/mdBook · error

The "{}" renderer failed

Error message

The "{}" renderer failed

What it means

After waiting for an external renderer (backend command) to finish, if the process exits with a non-zero status the render() call bails with this error. The renderer's own stderr/stdout is what explains the actual failure.

Source

Thrown at crates/mdbook-driver/src/builtin_renderers/mod.rs:83

        let mut stdin = child.stdin.take().expect("Child has stdin");
        if let Err(e) = serde_json::to_writer(&mut stdin, &ctx) {
            // Looks like the backend hung up before we could finish
            // sending it the render context. Log the error and keep going
            warn!("Error writing the RenderContext to the backend, {}", e);
        }

        // explicitly close the `stdin` file handle
        drop(stdin);

        let status = child
            .wait()
            .with_context(|| "Error waiting for the backend to complete")?;

        trace!("{} exited with output: {:?}", self.cmd, status);

        if !status.success() {
            error!("Renderer exited with non-zero return code.");
            bail!("The \"{}\" renderer failed", self.name);
        } else {
            Ok(())
        }
    }
}

View on GitHub (pinned to dc21064fc2)

Solutions

  1. Inspect the renderer's stderr/stdout printed above this error for the root cause
  2. Run the renderer command manually with the same environment to reproduce
  3. Fix or update the backend command in [output.<name>] (command = ...) configuration

Example fix

// before (book.toml)
[output.custom]
command = "python3 render.py"
// after (pin an interpreter that exists and test it)
[output.custom]
command = "/usr/bin/env python3 /path/to/render.py"
Defensive patterns

Strategy: try-catch

Validate before calling

// smoke-test the renderer command before wiring it into book.toml
let status = std::process::Command::new("render.py").arg("--version").status()?;
assert!(status.success(), "renderer command is not runnable");

Try / catch

if let Err(e) = render(ctx) {
    if e.to_string().contains("renderer failed") {
        eprintln!("backend exited non-zero; see its stderr above for the root cause");
    }
    return Err(e);
}

Prevention

When it happens

Trigger: The backend command (e.g. an alternate HTML renderer or a custom preprocessor-as-renderer) exits non-zero — crash, bad config passed via environment, missing templates/assets, or command not behaving as expected.

Common situations: Custom renderers failing due to missing output directory permissions, broken templates, or version incompatibility with the RenderContext environment variables.


AI-assisted analysis of rust-lang/mdBook@dc21064fc2 (2026-09-01). Data as JSON: /api/errors/9bdcf3f59686205f. Report an issue: GitHub.