tiangolo/fastapi · error · ValueError
Number of markdown links does not match the number in the or
Error message
Number of markdown links does not match the number in the original document ({len(links)} vs {len(original_links)}) What it means
Raised by `replace_markdown_links` (scripts/doc_parsing_utils.py:323) as a ValueError when the number of markdown links `[text](url)` found in a translated document differs from the original English document. The translation pipeline rewrites link URLs (e.g. injecting a language code) using positional correspondence, so the link counts must match; a mismatch means a link was added, removed, or escaped differently.
Source
Thrown at scripts/doc_parsing_utils.py:323
link += f"{{{attributes}}}"
return link
def replace_markdown_links(
text: list[str],
links: list[MarkdownLinkInfo],
original_links: list[MarkdownLinkInfo],
lang_code: str,
) -> list[str]:
"""
Replace markdown links in the given text with the original links.
Fail if the number of links does not match the original.
"""
if len(links) != len(original_links):
raise ValueError(
"Number of markdown links does not match the number in the "
"original document "
f"({len(links)} vs {len(original_links)})"
)
modified_text = text.copy()
for i, link_info in enumerate(links):
link_text = link_info["text"]
link_title = link_info["title"]
original_link_info = original_links[i]
# Replace
replacement_link = _construct_markdown_link(
url=original_link_info["url"],
text=link_text,
title=link_title,
attributes=original_link_info["attributes"],
lang_code=lang_code,View on GitHub (pinned to 3e8d1526d8)
Solutions
- Restore the same number of markdown links as the English source, in the same order.
- Keep `` distinct from text links; do not convert one into the other.
- Re-sync the translation from the latest English doc to recover link structure.
Example fix
// before (translation has 1 link, English has 2) See [docs](/docs). // after See [docs](/docs) and [tutorial](/tutorial).
Defensive patterns
Strategy: validation
Validate before calling
from scripts.doc_parsing_utils import extract_markdown_links
def markdown_link_counts_match(translated_lines, en_lines) -> bool:
return len(extract_markdown_links(translated_lines)) == len(extract_markdown_links(en_lines)) Type guard
def same_markdown_link_count(translated_lines, en_lines) -> bool:
from scripts.doc_parsing_utils import extract_markdown_links
return len(extract_markdown_links(translated_lines)) == len(extract_markdown_links(en_lines)) Prevention
- Preserve every markdown link (same count and order) when translating.
- Keep images  and links [..](..) distinct.
- Do not escape links with backslashes unless the source does.
When it happens
Trigger: Running the docs translation check on a file where a translator removed a link, converted `[text](url)` to plain text, or added a new link. An image `` was turned into a link, or a link escaped as `\[...\]` incorrectly.
Common situations: Translators dropping links they deemed irrelevant. Splitting/merging paragraphs that changed link count. Escape-character differences (`\[` vs `[`). Links wrapped differently across line breaks.
Related errors
- Number of code include placeholders does not match the numbe
- Number of headers with permalinks does not match the number
- Header levels do not match between document and original doc
- Number of HTML links does not match the number in the origin
- Code block (lines {start_line}-{end_line_no}) has different
AI-assisted analysis of tiangolo/fastapi@3e8d1526d8 (2026-08-11).
Data as JSON: /api/errors/0ce885132c37cc9d.
Report an issue: GitHub.