tiangolo/fastapi · error · ValueError

Code block (lines {start_line}-{end_line_no}) has different

Error message

Code block (lines {start_line}-{end_line_no}) has different number of lines than the original block ({len(block_a['content'])} vs {len(block_b['content'])})

What it means

Raised by replace_multiline_code_block() in scripts/doc_parsing_utils.py:590 when synchronizing translated documentation code blocks against the English originals. The function preserves translator comments by line-matching each translated code fence line to the corresponding English line, so it requires the two fenced blocks to have identical line counts. If a translator added, removed, or re-wrapped lines inside a fenced code block, the 1:1 comment preservation algorithm cannot run and the function refuses to silently corrupt the output.

Source

Thrown at scripts/doc_parsing_utils.py:590

) -> list[str]:
    """
    Replace multiline code block `a` with block `b` leaving comments intact.

    Syntax of comments depends on the language of the code block.
    Raises ValueError if the blocks are not compatible (different languages or different number of lines).
    """

    start_line = block_a["start_line_no"]
    end_line_no = start_line + len(block_a["content"]) - 1

    if block_a["lang"] != block_b["lang"]:
        raise ValueError(
            f"Code block (lines {start_line}-{end_line_no}) "
            "has different language than the original block "
            f"('{block_a['lang']}' vs '{block_b['lang']}')"
        )
    if len(block_a["content"]) != len(block_b["content"]):
        raise ValueError(
            f"Code block (lines {start_line}-{end_line_no}) "
            "has different number of lines than the original block "
            f"({len(block_a['content'])} vs {len(block_b['content'])})"
        )

    block_language = block_a["lang"].lower()
    if block_language in {"mermaid"}:
        if block_a != block_b:
            print(
                f"Skipping mermaid code block replacement (lines {start_line}-{end_line_no}). "
                "This should be checked manually."
            )
        return block_a["content"].copy()  # We don't handle mermaid code blocks for now

    code_block: list[str] = []
    for line_a, line_b in zip(block_a["content"], block_b["content"], strict=False):
        line_a_comment: str | None = None
        line_b_comment: str | None = None

View on GitHub (pinned to 3e8d1526d8)

Solutions

  1. Open the translated file at the line range printed in the message and add or remove lines so the fenced block matches the English block's line count.
  2. Re-run the docs check; if auto_fix was enabled the script prints 'Fixing multiline code blocks in: <path>' once counts align.
  3. If the English source legitimately changed, copy the new English block into the translation and re-apply only the translated comments line-by-line.
  4. For mermaid blocks the script skips replacement automatically (scripts/doc_parsing_utils.py:597) — if the block is mermaid, verify the lang tag is set so it is skipped.

Example fix

// before (translated file, English has 3 lines)
```Python
from fastapi import FastAPI
app = FastAPI()
```
// after (add the missing line to match English line count)
```Python
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
```
Defensive patterns

Strategy: validation

Validate before calling

from scripts.doc_parsing_utils import extract_multiline_code_blocks

def assert_blocks_match(en_lines: list[str], translated_lines: list[str]) -> None:
    en = extract_multiline_code_blocks(en_lines)
    tr = extract_multiline_code_blocks(translated_lines)
    assert len(en) == len(tr), f"block count {len(tr)} != en {len(en)}"
    for i, (a, b) in enumerate(zip(tr, en)):
        assert len(a['content']) == len(b['content']), (
            f"block {i} (line {a['start_line_no']}): "
            f"{len(a['content'])} != {len(b['content'])}"
        )

Try / catch

try:
    fixed = replace_multiline_code_blocks_in_text(doc_lines, doc_blocks, en_blocks)
except ValueError as e:
    logging.error(f"Code block mismatch in {path}: {e}")
    # surface the file/line range to the translator; do not auto-rewrite

Prevention

When it happens

Trigger: Called from check_translation() (scripts/doc_parsing_utils.py:726) which runs over every translated .md file pairing each translated fenced block (block_a) with the English block (original/b). Triggers when len(translated_block['content']) != len(english_block['content']) for any paired fenced code block. The message reports the line range of the offending block in the translated doc and both line counts.

Common situations: A translator hand-edited a Python/bash/YAML snippet and added a line, deleted a line, or split one statement into two. The English source changed (added/removed lines) and the translation was not yet re-synced. A fenced block in the translation was merged with adjacent text or had its fence moved.

Related errors


AI-assisted analysis of tiangolo/fastapi@3e8d1526d8 (2026-08-11). Data as JSON: /api/errors/6444cfa72ebdde4b. Report an issue: GitHub.