koala73/worldmonitor · error · Error
${pagePath} renders literal markdown emphasis in <main>
Error message
${pagePath} renders literal markdown emphasis in <main> What it means
assertCountryBriefPresentation validates the published page: it extracts the <main> HTML and throws if it contains the literal sequence '**', meaning markdown emphasis was not converted or stripped before publishing. Publish rules require markdown emphasis to be stripped, so raw '**' in <main> indicates a leaky render pipeline that would show raw markdown syntax to readers and crawlers.
Solutions
- Run the brief content through the publish-time markdown-emphasis stripping helper before rendering
- Locate the '**' occurrence in the page content and remove or properly convert it in the source data
- Render the field through the same formatter used for validated brief fields instead of raw interpolation
- If '**' is intentional content, rephrase or escape it to avoid the forbidden sequence
Example fix
// before
<main><p>${brief.text}</p></main> // renders "**critical**"
// after
<main><p>${stripMarkdownEmphasis(brief.text)}</p></main> // renders "critical" Defensive patterns
Strategy: validation
Validate before calling
const main = corpusMainHtml(html);
if (main.includes('**')) {
throw new Error(`${pagePath}: literal markdown emphasis leaked into <main>`);
} Try / catch
try {
assertCountryBriefPresentation({ pagePath, html, sources });
} catch (err) {
if (err.message.includes('literal markdown emphasis')) {
console.error(`Raw markdown rendered for ${pagePath}; route content through stripMarkdownEmphasis()`);
}
throw err;
} Prevention
- Route every brief field through the shared emphasis-stripping/formatter helper; never interpolate raw model output
- Strip markdown emphasis at content-freeze time so unformatted text cannot enter the pipeline later
- Lint generated content for '**' and other markdown syntax before rendering
- If content legitimately needs '**', escape or rephrase it at authoring time
When it happens
Trigger: Running assertCountryBriefPresentation({ pagePath, html, sources }) on HTML whose <main> contains '**'. Typically a brief text with markdown bold/italic passed through without the emphasis-stripping step, or a data string containing '**' interpolated as plain text.
Common situations: Brief content generated by a model containing markdown emphasis that bypassed the strip/render step; a new field rendered into the page without going through the shared emphasis-stripping helper; a legitimate '**' in the content (e.g. exponentiation or wildcard text).
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- is missing methodology prose
- is missing following prose
- profile "' + profile.name + '" has no prose
- H2 "' + page.heading + '" has no following content
- Comparison measurement requires the captured snapshot date
AI-assisted analysis of koala73/worldmonitor@7d06c8633d (2026-09-15).
Data as JSON: /api/errors/974f0ef841529477.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/build-crawlable-corpus.mjs:3572
function corpusVisibleText(html) {
return corpusMainHtml(html).replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim();
}
function intelBriefHtml(html) {
const match = corpusMainHtml(html).match(/<div\b[^>]*\bdata-intel-brief\b[^>]*>([\s\S]*?)<\/div>/i);
return match ? match[1] : null;
}
// #7738: prerendered country briefs were injected as escaped markdown, so
// crawlers saw literal `**` and `WHAT THIS MEANS FOR NO`. Fail the build
// when either artifact reaches <main>, including section titles that are
// still plain text rather than <h*> tags.
const MEANS_FOR_ISO_RE = /^\s*what this means for [a-z]{2}(?=\s*(?::|$))/im;
export function assertCountryBriefPresentation({ pagePath, html, sources }) {
const main = corpusMainHtml(html);
if (main.includes('**')) {
throw new Error(`${pagePath} renders literal markdown emphasis in <main>`);
}
const brief = intelBriefHtml(html);
if (brief && sources !== undefined) {
// Check the rendered claim blocks as well as the input. A later formatter
// must not add an entity or change a citation after publish-time validation.
const claims = [...brief.matchAll(/<(p|li)\b([^>]*)>([\s\S]*?)<\/\1>/gi)]
.filter((match) => !/\bclass="source"/.test(match[2]))
.map((match) => corpusVisibleText(match[3]).replace(/&(amp|lt|gt|quot|#39);/g,
(entity) => ({ '&': '&', '<': '<', '>': '>', '"': '"', ''': "'" })[entity]));
const gap = briefCitationGroundingGap({ text: claims.join('\n'), sources });
if (gap) throw new Error(`${pagePath} brief has unsupported citation: ${gap}`);
}
const headingSource = brief ?? main;
const headingHits = [...headingSource.matchAll(/<h[1-6]\b[^>]*>([\s\S]*?)<\/h[1-6]>/gi)];
for (const hit of headingHits) {
const text = hit[1].replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim();
if (MEANS_FOR_ISO_RE.test(text)) {
throw new Error(`${pagePath} heading leaks ISO code: ${text}`);View on GitHub (pinned to 7d06c8633d)