Documentation Build Troubleshooting

Last updated: July 22, 2026 Document type: Developer guide

For developers working on SDK documentation: understand common Sphinx/MyST build errors and how to fix them.


Quick diagnostic checklist

Before pushing documentation changes:

# Install dev dependencies
pip install -e ".[dev]"

# Test 1: Run full pre-commit suite (runs locally before commits)
pre-commit run --all-files

# Test 2: Build documentation in strict mode (matches RTD)
python -m sphinx -W --keep-going -b html ./docs ./docs/_build/html-strict

# Test 3: Check markdown syntax
pymarkdown --config .pymarkdown scan README.md GETTING_STARTED.md

# Test 4: Quick validation of key files
python src/britecore_sdk/utils/check_markdown_structure.py

If all tests pass, your changes are ready to commit and push.


Common documentation build errors

Error: “adjacent transitions are not allowed”

Cause: Two or more --- (docutils transition markers) are adjacent with no content between them.

Example (❌ WRONG):

Some paragraph.

---

---

Next section.

Fix:

Some paragraph.

---

Next section.

Prevention:

  • Review markdown structure visually — each --- should have content both before and after it

  • Run Sphinx build locally before committing: python -m sphinx -W --keep-going -b html ./docs ./docs/_build/html-strict


Error: “Unknown substitution referenced”

Cause: Reference to a MyST substitution that isn’t defined in docs/conf.py.

Example (❌ WRONG):

Built on {{ unknown_substitution }}

Fix: Add the substitution to docs/conf.py:

myst_substitutions = {
    "docs_version": release,
    "unknown_substitution": "value",  # ← Add here
}

Prevention:

  • Only use substitutions defined in docs/conf.py

  • Current substitutions: docs_version, docs_commit, docs_commit_date, docs_build_date


Error: “Inline code cannot contain MyST substitutions”

Cause: MyST substitutions don’t expand inside backtick inline code spans.

Example (❌ WRONG):

See `{{ docs_commit }}`

Fix (bare text or separate from code):

See {{ docs_commit }}

Or in code blocks:
\`\`\`
commit: {{ docs_commit }}
\`\`\`

Prevention:

  • Never wrap MyST substitutions in backticks

  • Keep substitutions as bare text or inside code fences, not inline code


Error: “Incomplete markup constructs”

Cause: Markdown table syntax is malformed or incomplete.

Example (❌ WRONG):

| Column 1 | Column 2
| --- | ---
| Value 1 | Value 2

Fix:

| Column 1 | Column 2 |
| --- | --- |
| Value 1 | Value 2 |

Prevention:

  • All table rows must have the same number of columns

  • Closing | is required on each row

  • Test markdown syntax with: pymarkdown --config .pymarkdown scan FILENAME.md


Error: “Unknown role/directive”

Cause: Using a Sphinx directive or role that isn’t enabled or recognized.

Example (❌ WRONG):

:::{unknown-directive}
Content
:::

Fix: Check if the directive is:

  1. Built-in: Use correct syntax (e.g., note, warning, code-block)

  2. Extension-based: Verify extension is loaded in docs/conf.py

  3. Custom: Define in docs/conf.py or use existing ones

Prevention:

  • Check .rst/MyST documentation for valid directives

  • Verify extensions in docs/conf.py: extensions = [...]


Error: “Document title underline too short/too long”

Cause: RST title underlines don’t match the title length.

Example (❌ WRONG):

# Main Title
===

Fix:

# Main Title
=============

Or use markdown-style headings in .md files (MyST handles this automatically):

# Main Title

## Subsection

Prevention:

  • Use markdown heading syntax (#, ##) in .md files

  • MyST converts these properly to RST for Sphinx


Prevention: Git hooks and pre-commit

Enable pre-commit hooks

Pre-commit hooks automatically validate your changes before committing:

# Install pre-commit framework
pip install pre-commit

# Install hooks from config
pre-commit install

# (Optional) Test hooks on all files
pre-commit run --all-files

What the hooks check

  1. markdown-structure — Python-based markdown validation

  2. pymarkdown — Markdown linting (MD001-MD047 rules)

  3. sphinx-build — Full documentation build with -W (treat warnings as errors)

  4. ruff + black — Code formatting and linting

  5. mypy — Type checking

  6. pytest-unit — Quick unit test smoke check


Best practices for documentation changes

  1. Make incremental changes — Edit one section at a time, test with Sphinx build after each section.

  2. Validate before committing — Run full pre-commit suite locally:

    pre-commit run --all-files
    
  3. Structure matters — Review markdown structure visually:

    • Headings are hierarchical (#, ##, ###)

    • Transitions (---) have content before and after

    • Tables have matching column counts

    • Code blocks are properly closed

  4. Test locally = test in CI — If it passes locally, it passes CI:

    • CI runs the same pre-commit hooks

    • CI runs Sphinx with the same flags (-W --keep-going)

  5. Use examples from working files — Copy patterns from:

    • README.md — top-level documentation

    • GETTING_STARTED.md — guide-style documentation

    • docs/ASYNC_CACHING.md — detailed technical documentation

  6. Document your assumptions — If adding new substitutions, integration points, or event types, update this file too.


Running pre-commit in different scenarios

Before commit (automatic if hooks installed)

git commit -m "message"
# pre-commit runs automatically

Before push (also automatic)

git push origin master
# pre-commit run --hook-stage pre-push runs (release compliance check)

Manual validation (for debugging)

# Check all files
pre-commit run --all-files

# Check specific hook
pre-commit run sphinx-build --all-files

# Dry-run to see what would change
pre-commit run --all-files --verbose

In CI/GitHub Actions

# Runs the same as local: --all-files by default
python -m pre_commit run --all-files