rust-lang/mdBook · error

theme dir {} does not exist

Error message

theme dir {} does not exist

What it means

When output.html.theme is set in book.toml, mdBook joins that path against the book root and requires it to be an existing directory containing custom theme files. If the configured directory doesn't exist, rendering aborts with this error so the user notices a bad theme path instead of silently using defaults.

Source

Thrown at crates/mdbook-html/src/html_handlebars/hbs_renderer.rs:328

        let html_config = ctx.config.html_config().unwrap_or_default();
        let src_dir = ctx.root.join(&ctx.config.book.src);
        let destination = &ctx.destination;
        let book = &ctx.book;
        let build_dir = ctx.root.join(&ctx.config.build.build_dir);

        if destination.exists() {
            fs::remove_dir_content(destination)
                .with_context(|| "Unable to remove stale HTML output")?;
        }

        trace!("render");
        let mut handlebars = Handlebars::new();

        let theme_dir = match html_config.theme {
            Some(ref theme) => {
                let dir = ctx.root.join(theme);
                if !dir.is_dir() {
                    bail!("theme dir {} does not exist", dir.display());
                }
                dir
            }
            None => ctx.root.join("theme"),
        };

        let theme = Theme::new(theme_dir);

        debug!("Register the index handlebars template");
        handlebars.register_template_string("index", String::from_utf8(theme.index.clone())?)?;

        debug!("Register the head handlebars template");
        handlebars.register_partial("head", String::from_utf8(theme.head.clone())?)?;

        debug!("Register the redirect handlebars template");
        handlebars
            .register_template_string("redirect", String::from_utf8(theme.redirect.clone())?)?;

View on GitHub (pinned to dc21064fc2)

Solutions

  1. Create the configured theme directory or fix the path in book.toml so it points at an existing directory relative to the book root.
  2. Remove the `theme = ...` line from [output.html] to fall back to the default theme (or the built-in theme dir).
  3. Run `mdbook theme` (or copy the default theme out) to scaffold the theme directory, then customize it.

Example fix

// before (book.toml)
[output.html]
theme = "./my-them"

// after
[output.html]
theme = "./my-theme"
Defensive patterns

Strategy: validation

Validate before calling

// Before invoking mdbook
const theme = config['output.html.theme'];
if (theme && !fs.existsSync(path.join(bookRoot, theme))) {
  throw new Error(`theme dir missing: ${path.join(bookRoot, theme)}`);
}

Prevention

When it happens

Trigger: Calling MdBook::load/build with [output.html] theme = "path" where root.join(path) is not a directory: typo in the path, path relative to the wrong directory, or the theme directory was deleted/moved before running mdbook build.

Common situations: Cloning a book repo where the custom theme dir wasn't committed (e.g. ignored by .gitignore); renaming the theme folder; running mdbook from a different working directory than expected.

Related errors


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