rust-lang/mdBook · error

redirect found for existing chapter at `{path}` Either delet

Error message

redirect found for existing chapter at `{path}`
Either delete the redirect or remove the chapter.

What it means

collect_redirects_for_path checks, before rendering a chapter, whether output.html.redirect defines a redirect whose source equals the chapter's URL path. Redirects and real chapters must be mutually exclusive; if a redirect would shadow an existing chapter, the build fails with this error to make the conflict explicit.

Source

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

        } else {
            let e = combined.entry(original.to_string()).or_default();
            e.0 = new.clone();
        }
    }
    combined
}

/// Collects fragment redirects for an existing page.
///
/// The returned map has keys like `#foo` and the value is the new destination
/// path or URL.
fn collect_redirects_for_path(
    path: &Path,
    redirects: &HashMap<String, String>,
) -> Result<BTreeMap<String, String>> {
    let path = format!("/{}", path.to_url_path());
    if redirects.contains_key(&path) {
        bail!(
            "redirect found for existing chapter at `{path}`\n\
            Either delete the redirect or remove the chapter."
        );
    }

    let key_prefix = format!("{path}#");
    let map = redirects
        .iter()
        .filter_map(|(source, dest)| {
            source
                .strip_prefix(&key_prefix)
                .map(|fragment| (format!("#{fragment}"), dest.to_string()))
        })
        .collect();
    Ok(map)
}

View on GitHub (pinned to dc21064fc2)

Solutions

  1. Delete the conflicting entry from [output.html.redirect] in book.toml.
  2. Remove or rename the chapter at that path in SUMMARY.md if the redirect is the intended behavior.
  3. Adjust the redirect key to a different source path if both pages should exist.

Example fix

// before (book.toml)
[output.html.redirect]
"guide/intro.html" = "guide/index.html"
// while src/guide/intro.md still exists in SUMMARY.md

// after: remove the redirect line
[output.html.redirect]
Defensive patterns

Strategy: validation

Validate before calling

// Ensure no redirect source matches a SUMMARY chapter path
for (const redirect of Object.keys(config['output.html.redirect'] || {})) {
  if (chapterPaths.includes(redirect)) {
    throw new Error(`redirect ${redirect} conflicts with an existing chapter`);
  }
}

Prevention

When it happens

Trigger: A SUMMARY.md chapter is rendered at path P while [output.html.redirect] contains a key "/P" (or "/P#fragment" via the key_prefix check) for the same path — e.g. a chapter was re-added after a redirect stub was configured for its old location.

Common situations: Restructuring a book: a page was renamed and a redirect added, then a chapter was moved back to the original path without deleting the redirect; merging branches where one added a redirect and another restored the chapter.

Related errors


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