rust-lang/mdBook · error

expected bool for `{optional_key}`: {e}

Error message

expected bool for `{optional_key}`: {e}

What it means

The command-based renderer reads `output.<name>.optional` expecting a boolean. If Config::get() fails (typically because the value exists but is not a bool, or get() rejects the key shape), it bails with this message.

Source

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

impl CmdRenderer {
    /// Create a new `CmdRenderer` which will invoke the provided `cmd` string.
    pub fn new(name: String, cmd: String) -> CmdRenderer {
        CmdRenderer { name, cmd }
    }
}

impl Renderer for CmdRenderer {
    fn name(&self) -> &str {
        &self.name
    }

    fn render(&self, ctx: &RenderContext) -> Result<()> {
        info!("Invoking the \"{}\" renderer", self.name);

        let optional_key = format!("output.{}.optional", self.name);
        let optional = match ctx.config.get(&optional_key) {
            Ok(Some(value)) => value,
            Err(e) => bail!("expected bool for `{optional_key}`: {e}"),
            Ok(None) => false,
        };

        let _ = fs::create_dir_all(&ctx.destination);

        let mut cmd = crate::compose_command(&self.cmd, &ctx.root)?;
        let mut child = match cmd
            .stdin(Stdio::piped())
            .stdout(Stdio::inherit())
            .stderr(Stdio::inherit())
            .current_dir(&ctx.destination)
            .spawn()
        {
            Ok(c) => c,
            Err(e) => {
                return crate::handle_command_error(
                    e, optional, "output", "backend", &self.name, &self.cmd,
                );

View on GitHub (pinned to dc21064fc2)

Solutions

  1. Remove the quotes so the value is a real TOML boolean: optional = true
  2. Delete the optional key if the backend is mandatory
  3. Validate book.toml types (e.g. with a TOML linter) before building

Example fix

// before (book.toml)
[output.mybackend]
optional = "true"
// after
[output.mybackend]
optional = true
Defensive patterns

Strategy: validation

Validate before calling

let raw = toml::from_str::<toml::Value>(&std::fs::read_to_string("book.toml")?)?;
if let Some(o) = raw.get("optional") {
    assert!(o.is_bool(), "output.<name>.optional must be an unquoted boolean");
}

Try / catch

match ctx.config.get::<bool>(&optional_key) {
    Ok(v) => v.unwrap_or(false),
    Err(e) if e.to_string().contains("expected bool") => {
        eprintln!("fix {optional_key} in book.toml: must be true/false, unquoted");
        return Err(e);
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: book.toml setting `output.<name>.optional = "true"` (string) or a number/table instead of a boolean; a config value that fails deserialization to bool.

Common situations: Quoted booleans in hand-edited book.toml; TOML users copying JSON-style config where true is quoted.

Related errors


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