Skip to content

fix(docs): escape MDX braces in generated reference pages - #90

Merged
BaptisteGi merged 1 commit into
mainfrom
fix-docs-mdx-brace-escaping
Sep 4, 2026
Merged

fix(docs): escape MDX braces in generated reference pages#90
BaptisteGi merged 1 commit into
mainfrom
fix-docs-mdx-brace-escaping

Conversation

@petercrocker

Copy link
Copy Markdown
Contributor

Problem

Docusaurus parses the generated reference pages as MDX, where a bare {...} is a JSX expression rather than literal text. Any schema description containing braces breaks the docs build:

Error: Can't render static file for pathname "/reference/module_port"
  cause: Objects are not valid as a React child (found: object with keys {children, exports})

module happens to be a real binding in MDX module scope, so a NetBox port-name token like Ethernet{module}/1 silently renders the MDX module object instead of failing on an undefined name.

Found while rebasing #76, whose module_port extension is the first schema in the library to put braces in a description.

Why the existing CI doesn't protect against this

Check generated documentation is up to date passes happily, because the regenerated MDX matches the committed MDX — the docs are consistently generated and consistently unbuildable. Only validate-documentation, which runs afterwards, catches it. Anyone writing a braced description hits this at the very end of a CI run, with an error that names React rather than their schema.

Changes

tasks/docs.py

Escape braces in everything rendered as MDX prose or into a Markdown table. Two things are deliberately left alone:

  • The code section. It lands inside a fenced block, where MDX ignores braces and an escape would show up verbatim in the rendered YAML. This matters — several schemas have jinja2_template: "{{ device__name__value }}", which must survive intact.
  • Inline code spans. Braces inside them are already inert, and a backslash there renders literally rather than escaping. Blindly escaping would corrupt a description that had already worked around this with backticks (as module_port does in feat(dcim): support NetBox device-type and module-type imports #76).

tests/, pyproject.toml, .github/workflows/ci.yml

Those two carve-outs are subtle enough to regress unnoticed, so they get unit tests — the repo's first. Adds pytest to the dev group, points it at the repo root so the top-level tasks package imports, and runs it in the existing python-lint job.

Verification

This changes no generated output. No description on main contains braces today, so regenerating produces a zero-line diff. It removes a trap rather than fixing a visible symptom.

Proven by temporarily giving extensions/cable/cable.yml an unbackticked description:

description: "Probe: port name e.g. 'Ethernet{module}/1' plus {a}."

Generated MDX — escaped in prose, untouched in the code fence:

17:- **Description:** Probe: port name e.g. 'Ethernet\{module\}/1' plus \{a\}.
40:  description: 'Probe: port name e.g. ''Ethernet{module}/1'' plus {a}.'

npm run build then succeeds where it previously failed, and the rendered HTML contains the literal Ethernet{module}/1 plus {a} with zero [object Object] and no leaked backslashes. Probe reverted before committing.

ruff, ruff format, mypy, pylint (10.00/10), yamllint and 12 unit tests all pass.

Notes for reviewers

  • The CI line is one step in the existing python-lint job. If you'd rather tests live in their own job, or not run in CI yet, that step is trivially droppable without touching the fix.
  • Related but deliberately not fixed here: invoke docs.generate also overwrites every extensions/*/README.md with a fixed stub, clobbering hand-written notes in location_minimal, location_site and rack. And docs/docs/reference/security.mdx is stale against its schema. Both are separate pre-existing issues.

Docusaurus parses the generated reference pages as MDX, where a bare
`{...}` is a JSX expression rather than literal text. Any schema
description containing braces therefore breaks the docs build:

    Error: Can't render static file for pathname "/reference/module_port"
      cause: Objects are not valid as a React child
             (found: object with keys {children, exports})

`module` happens to be a real binding in MDX module scope, so a NetBox
port-name token like `Ethernet{module}/1` renders the MDX module object
rather than failing loudly on an undefined name.

Nothing on main trips this today, so this commit changes no generated
output - it removes a trap. The `validate-documentation` job is the only
thing that catches it, and it runs after `Check generated documentation
is up to date`, which passes happily because the regenerated MDX matches
the committed MDX. The docs are consistently generated and consistently
unbuildable.

tasks/docs.py
  Escape braces in everything rendered as MDX prose or into a Markdown
  table, leaving the `code` section alone - it lands inside a fenced
  block, where MDX ignores braces and an escape would show up verbatim
  in the rendered YAML.

  Inline code spans are skipped too. Braces inside them are already
  inert, and a backslash there renders literally rather than escaping,
  so blindly escaping would corrupt a description that had already
  worked around this by using backticks.

tests/, pyproject.toml, .github/workflows/ci.yml
  The escaping rules above are subtle enough to regress unnoticed, so
  they get unit tests - the repo's first. Adds pytest to the dev group,
  points it at the repo root so the top-level `tasks` package imports,
  and runs it in the existing python-lint job.

Verified by temporarily giving a description an unbackticked
`Ethernet{module}/1`: before, the docs build fails as above; after, it
builds and renders the literal braces, with the code fence untouched.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying schema-library with  Cloudflare Pages  Cloudflare Pages

Latest commit: 2483d11
Status: ✅  Deploy successful!
Preview URL: https://3bcce2bd.schema-library.pages.dev
Branch Preview URL: https://fix-docs-mdx-brace-escaping.schema-library.pages.dev

View logs

@petercrocker
petercrocker marked this pull request as ready for review September 3, 2026 21:08
@BaptisteGi
BaptisteGi merged commit 20ae95e into main Sep 4, 2026
8 checks passed
@BaptisteGi
BaptisteGi deleted the fix-docs-mdx-brace-escaping branch September 4, 2026 07:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants