fix(docs): escape bare < for Fern MDX + harden MDX checker#1367
Conversation
Fern parses docs as MDX, which treats a bare `<` followed by a name
character as the start of a JSX tag. `landed <30 s` tripped the
v0.15.0-rc2 Publish Fern Docs job ("Unexpected character `3` before
name"). Escape it as `\<30 s`, which renders as a literal `<` in both
MDX and GitHub CommonMark. A sweep of all 31 Fern-nav docs found this
to be the only remaining bare-`<` prose hazard (the `<13%` on line 162
is inside a fenced code block, which MDX leaves literal).
|
🌿 Preview your docs: https://nvidia-preview-fix-fern-mdx-escape-lt.docs.buildwithfern.com/aicr |
|
Caution Review failedPull request was closed or merged during review No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Enterprise Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughA single sentence in Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
tools/check-docs-mdx is the local + PR-CI guard for MDX-unsafe markdown, but its bare-tag check only matched `<` followed by a letter (`<[a-zA-Z]`). MDX equally rejects `<` before a digit, so `<30 s` and `<13%` slipped through and only surfaced when `fern generate` ran on the release tag (v0.15.0-rc2). Broaden the match to `<[0-9a-zA-Z]`. Also fix the escape-stripping: it only removed paired `\<...\>`, so a lone `\<30 s` would now false-positive. Strip `\<` and `\>` individually instead, matching the documented `\<name\>` escape guidance. Verified: the checker passes the current tree and flags a bare `<30 s` / `<13%` while treating `\<...\>` and backticked `<...>` as safe.
Coverage Report ✅
Coverage BadgeNo Go source files changed in this PR. |
tools/check-docs-mdx excluded recipe-health.md on the assumption it
carried HTML-comment splice markers VitePress needs. That file is now
Fern-published and uses MDX-safe {/* ... */} markers, so the exclusion
was a blind spot (it is why the recipe-health.md HTML comment reached
the rc1 publish). Drop the exclusion and teach the checker to treat
{/* ... */} comments (single- and multi-line) as safe, so the valid
markers don't false-positive the bare-brace check while real hazards
after a comment on the same line are still caught.
container-images.md stays excluded (HTML markers, not Fern-published).
Help text for `make check-docs-mdx` updated to list all checks.
The greedy gsub(/{/*.*\*/}/) span from the first {/* to the last */} on
a line, deleting any real MDX hazard sitting between two separate
comments (e.g. `{/* a */} <30 s {/* b */}`) before the bare-<tag>,
brace, autolink, and HTML-comment checks ran — so exactly the
Fern-breaking pattern this tool guards against could evade it. Strip one
{/* ... */} segment at a time, preserving text between comments; an
unterminated {/* still opens the multi-line region.
ArangoGutierrez
left a comment
There was a problem hiding this comment.
Pulled the head tree and ran the new checker end to end. It does what the description says:
- Passes clean on the full docs tree, so the digit broadening doesn't add false positives.
- Catches a bare
<30 swhere the old<[a-zA-Z]regex missed it. \<30 s, backticked`<30 s`, and{/* ... */}(single and multi-line) all pass; a hazard after a same-line or multi-line comment close is still flagged.- recipe-health.md's license header and BEGIN/END splice markers are handled now that it's scanned.
Two latent edge cases in the comment handling, both inline below. Neither is hit by the current tree, and both are the same gap-class this PR closes, so I'd treat them as a fast follow rather than a blocker.
Separately, there's no regression test for the checker itself. A small testdata/ of pass/fail snippets would lock the behavior in and would have caught both edges below. Happy to send that plus the fixes as a follow-up.
Nothing here blocks unblocking the publish.
Two fixes to tools/check-docs-mdx, both raised in review of #1367: 1. Strip inline code spans BEFORE the MDX-comment detection. Previously a backticked, unterminated `{/*` (e.g. prose showing `{/*` as an example) opened a bogus multi-line comment region that swallowed every following line until EOF/`*/}`, hiding real hazards like a bare `<30 s`. 2. Wrap the per-file awk in the `if` condition. The script runs under `set -e`, and the awk exits 1 on a hazard, so the scan aborted at the first offending file and silently skipped the rest (the violations footer never printed). It still gated (non-zero exit) but under-reported; now every offending file is listed. Verified: full docs tree passes; a multi-file probe reports both a two-comments-on-one-line hazard and a backticked-`{/*` hazard, with the footer.
Summary
Unblock the Fern docs publish (MDX) and close the two gaps in the local MDX checker that let the breakage reach the release tag.
Motivation / Context
Fern parses docs as MDX, which treats a bare
<followed by a name-start character as a JSX tag.landed <30 sindocs/contributor/inference-perf-fluctuation.mdfailed thev0.15.0-rc2Publish Fern Docs job:There is already a local gate for this —
tools/check-docs-mdx, exposed asmake check-docs-mdxand wired intomake lint(hencemake qualify) and the PR-CIfern-docs-ci.yaml. It should have caught both this and the earlier recipe-health.md breakage, but had two gaps:<before a letter (<[a-zA-Z]), so<30 s/<13%slipped through.recipe-health.mdwas excluded (on a now-obsolete VitePress HTML-marker assumption) — which is why its HTML comment reached the rc1 publish.(
fern checkdoes not catch MDX parse errors, so publish was the first place these surfaced.)Fixes: N/A
Related: https://github.com/NVIDIA/aicr/actions/runs/27557526326
Type of Change
Component(s) Affected
docs/,examples/)tools/check-docs-mdx,make check-docs-mdx)Implementation Notes
Three commits:
<30 sas\<30 s(literal<in MDX and GitHub CommonMark).<13%on line 162 is inside a code fence, so MDX leaves it literal — consistent with the error pointing at<30(char3).<[0-9a-zA-Z], and strip\</\>individually so a lone\<escape doesn't false-positive.recipe-health.mdexclusion (it is Fern-published and now uses MDX-safe{/* ... */}markers), and teach the checker to treat{/* ... */}comments (single- and multi-line) as safe so the valid markers don't trip the bare-brace check while real hazards on the same line are still caught.container-images.mdstays excluded (HTML markers, not Fern-published).Testing
A sweep of all 31 Fern-nav docs found
<30 sto be the only remaining bare-<prose hazard and no stray{hazards beyond valid MDX comments.Risk Assessment
Rollout notes: With both checker gaps closed,
make lint/make qualifynow catch this class pre-merge — no separate pre-push hook needed.Checklist
make testwith-race) — N/Amake check-docs-mdx)git commit -S)