{"record":{"id":"8270fd4dc477b735","repo":"rust-lang/mdBook","slug":"unable-to-get-last-link-because-the-list-of-summar","errorCode":null,"errorMessage":"Unable to get last link because the list of SummaryItems doesn't contain any Links","messagePattern":"Unable to get last link because the list of SummaryItems doesn't contain any Links","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/mdbook-summary/src/lib.rs","lineNumber":624,"sourceCode":"            if let Some(ref mut number) = link.number {\n                number[level] += by;\n            }\n\n            update_section_numbers(&mut link.nested_items, level, by);\n        }\n    }\n}\n\n/// Gets a pointer to the last `Link` in a list of `SummaryItem`s, and its\n/// index.\nfn get_last_link(links: &mut [SummaryItem]) -> Result<(usize, &mut Link)> {\n    links\n        .iter_mut()\n        .enumerate()\n        .filter_map(|(i, item)| item.maybe_link_mut().map(|l| (i, l)))\n        .next_back()\n        .ok_or_else(|| {\n            anyhow::anyhow!(\n                \"Unable to get last link because the list of SummaryItems \\\n                 doesn't contain any Links\"\n            )\n        })\n}\n\n/// Removes the styling from a list of Markdown events and returns just the\n/// plain text.\nfn stringify_events(events: Vec<Event<'_>>) -> String {\n    events\n        .into_iter()\n        .filter_map(|t| match t {\n            Event::Text(text) | Event::Code(text) => Some(text.into_string()),\n            Event::SoftBreak => Some(String::from(\" \")),\n            _ => None,\n        })\n        .collect()\n}","sourceCodeStart":606,"sourceCodeEnd":642,"githubUrl":"https://github.com/rust-lang/mdBook/blob/dc21064fc21d955a0e1f67e65e336883c3e5260b/crates/mdbook-summary/src/lib.rs#L606-L642","documentation":"get_last_link retrieves the final Link in a list of SummaryItems, needed to append a nested item under it while parsing nested numbered chapters. If the list contains no Link items (filtered via maybe_link_mut yields nothing), the iterator is empty and this error is returned instead of panicking.","triggerScenarios":"parse_nested_numbered encounters a nested list whose preceding items contain no Link — e.g. the numbered list starts with a Spacer or draft/separator item and then indents a nested list, so next_back() finds no link to attach the nested chapter to.","commonSituations":"Placing a separator line (\"---\") at the start of the numbered section and indenting the first chapter under it; malformed SUMMARY where a nested list appears before any parent link; script-generated SUMMARY emitting lists without parents.","solutions":["Ensure each nested list in the numbered section is directly preceded by a chapter link (the parent).","Remove or move any separator/spacer item that appears before the first link of a numbered section.","Fix SUMMARY.md structure so nested items follow a valid parent link."],"exampleFix":"<!-- before: SUMMARY.md -->\n- ---\n  - [Child](child.md)\n\n<!-- after -->\n- [Parent](parent.md)\n  - [Child](child.md)","handlingStrategy":"validation","validationCode":"// Ensure every nested list has a preceding parent link\nlet prevWasLink = false;\nfor (const line of summary.split('\\n')) {\n  if (/^\\s{2,}-\\s\\[/.test(line) && !prevWasLink) throw new Error('nested list without parent link');\n  prevWasLink = /^-\\s\\[/.test(line);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never indent a chapter link under a separator or spacer line.","Keep the first entry of each numbered section unindented (a parent link)."],"tags":["summary","parse","nested-items","mdbook"],"backgroundTag":"nested-list-without-parent-link","analyzedSha":"dc21064fc21d955a0e1f67e65e336883c3e5260b","analyzedAt":"2026-09-01T10:15:12.134Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}