In my hugo papermod powered website where math is rendered by Katex, math blocks were silently failing to render mid-page. Everything after a certain point appeared as raw LaTeX. Here’s the fix.

NOTE: The fix is generated by Claude. It works. But I’m not sure if the mechanism is 100% correct. But it works.

Root Causes

1. Goldmark mangles math before KaTeX sees it

Hugo uses Goldmark as its Markdown renderer. Goldmark processes the .md file first — and it escapes or corrupts characters like \, _, {, } inside math delimiters. By the time KaTeX receives the string, the LaTeX is broken.

This is why \begin{align*} or \Sigma_{XX} would silently fail: the backslashes and braces were being eaten.

Fix: Enable the Goldmark passthrough extension in config.yaml. This tells Goldmark to leave content inside $...$ and $$...$$ completely untouched.

markup:
  goldmark:
    extensions:
      passthrough:
        enable: true
        delimiters:
          block:
            - - '$$'
              - '$$'
          inline:
            - - '$'
              - '$'

Requires Hugo ≥ v0.122.0.

2. $$ blocks not separated by blank lines

Goldmark only treats a $$ block as display math if it is surrounded by blank lines. Without them, it’s parsed as inline text inside a paragraph, which breaks rendering.

Fix: Ensure every $$ block has a blank line above and below it in the .md source.

3. align* is poorly supported in KaTeX

KaTeX has inconsistent support for standalone \begin{align*}. It works reliably when wrapped inside $$...$$ as \begin{aligned}.

Fix: Replace all \begin{align*} / \end{align*} with \begin{aligned} / \end{aligned}.

# macOS-compatible
perl -i -pe 's/\\begin\{align\*\}/\\begin{aligned}/g; s/\\end\{align\*\}/\\end{aligned}/g' your-post.md

Why One Failure Kills the Rest

KaTeX’s renderMathInElement stops processing subsequent expressions when it hits an error — unless throwOnError: false is set. This explains the “everything after point X breaks” symptom. E.g. put in ./layouts/partials/math.html the following code:

renderMathInElement(document.body, {
  delimiters: [
    {left: '$$', right: '$$', display: true},
    {left: '$',  right: '$',  display: false},
    {left: '\\[', right: '\\]', display: true},
    {left: '\\(', right: '\\)', display: false},
  ],
  throwOnError: false
});