FuelLabs/fuels-rs · error · anyhow::Error

file `{}` not in SUMMARY.md

Error message

file `{}` not in SUMMARY.md

What it means

Doc-checking error (scripts/check-docs): a markdown file exists under the mdbook src/ directory but is not referenced by SUMMARY.md. The check compares the canonicalized set of files listed in SUMMARY.md with files found by scanning the source tree; every .md file must be reachable from the book's table of contents.

Source

Thrown at scripts/check-docs/src/lib.rs:225

            path.canonicalize()
                .unwrap_or_else(|e| panic!("could not canonicalize md path: {e} {path:?}"))
        })
        .collect()
}

pub fn validate_md_files(
    md_files_summary: HashSet<PathBuf>,
    md_files_in_src: String,
) -> Vec<Error> {
    md_files_in_src
        .lines()
        .filter_map(|file| {
            let file = PathBuf::from(file)
                .canonicalize()
                .expect("could not canonicalize md path");

            (!md_files_summary.contains(&file))
                .then(|| anyhow!("file `{}` not in SUMMARY.md", file.to_str().unwrap()))
        })
        .collect()
}

pub fn search_for_pattern(pattern: &str, location: &str) -> anyhow::Result<String> {
    let grep_project = std::process::Command::new("grep")
        .arg("-H") // print filename
        .arg("-n") // print line-number
        .arg("-r") // search recursively
        .arg("--binary-files=without-match")
        .arg("--exclude-dir=check-docs")
        .arg(pattern)
        .arg(location)
        .output()
        .expect("failed grep command");

    if !grep_project.status.success() {
        bail!("Failed running `grep` command for pattern '{}'", pattern);

View on GitHub (pinned to d9a250a518)

Solutions

  1. If the page should ship: add an entry (or an inline [link](page.md)) to SUMMARY.md at the right position in the chapter list.
  2. If the page is a draft/leftover: delete it or move it outside the mdbook src directory.
  3. If a file was renamed, update SUMMARY.md to the new path so the canonicalized sets match.
  4. Re-run the check-docs tooling to confirm.

Example fix

# before: docs/src/advanced/storage.md exists but is unlisted
# SUMMARY.md
# [Intro](intro.md)
# after
# Summary
[Intro](intro.md)
# Advanced
- [Storage](advanced/storage.md)
Defensive patterns

Strategy: validation

Validate before calling

let summary_files: HashSet<PathBuf> = parse_summary_entries("docs/src/SUMMARY.md")
    .into_iter().filter_map(|p| p.canonicalize().ok()).collect();
for md in walkdir::WalkDir::new("docs/src").into_iter().filter_map(Result::ok) {
    if md.path().extension() == Some("md".as_ref()) {
        let c = md.path().canonicalize()?;
        assert!(summary_files.contains(&c) || md.path().ends_with("SUMMARY.md"), "{} not referenced in SUMMARY.md", md.path().display());
    }
}

Prevention

When it happens

Trigger: Adding a markdown page under docs/src (or wherever the mdbook source lives) without adding a corresponding entry/link in SUMMARY.md; leaving draft or moved pages in the tree; renaming a file that SUMMARY.md still lists under the old name (old name disappears from the summary set, new file is orphaned).

Common situations: Draft pages committed accidentally; docs restructures that move files into subdirectories without updating SUMMARY.md; deleted pages that still exist in the working tree.

Related errors


AI-assisted analysis of FuelLabs/fuels-rs@d9a250a518 (2026-08-16). Data as JSON: /api/errors/fa022cba91ce93e8. Report an issue: GitHub.