koala73/worldmonitor · error
needs a summary for the llms.txt Comparisons section
Error message
needs a summary for the llms.txt Comparisons section
What it means
comparisonDiscoveryEntries builds the llms.txt Comparisons section, listing each comparison page with its summary as the description. A page without a non-blank summary string cannot be advertised in llms.txt, so the build throws '<slug> needs a summary for the llms.txt Comparisons section'.
Solutions
- Add a concise one-to-two sentence summary string to the named page seed.
- Ensure the field is exactly summary (not description) on the merged page object.
- Confirm applyComparisonNarrative's merge isn't overwriting or dropping summary from the seed.
Example fix
// before
{
slug: 'chokepoint-monitoring-tools',
// no summary
}
// after
{
slug: 'chokepoint-monitoring-tools',
summary: 'Compare the leading chokepoint monitoring tools and how World Monitor tracks maritime chokepoints in real time.',
} Defensive patterns
Strategy: validation
Validate before calling
COMPARISON_PAGES.forEach((p) => {
if (typeof p.summary !== 'string' || !p.summary.trim()) throw new Error(`${p.slug} missing summary`);
}); Type guard
const hasSummary = (p) => typeof p?.summary === 'string' && p.summary.trim() !== '';
Prevention
- Include summary in the seed template/checklist for new comparison pages.
- Never use empty-string placeholders for summary in committed seeds.
When it happens
Trigger: Mapping COMPARISON_PAGES in comparisonDiscoveryEntries when a page's summary is undefined, not a string, an empty string, or whitespace-only (summary.trim() === '').
Common situations: New comparison page seed missing the summary field; summary defined as an empty placeholder ''; summary moved to a different field name (e.g. description) during a refactor; llms.txt discovery build run against seeds from another branch.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- ${pagePath} heading leaks ISO code: ${text}
- ${pagePath} brief heading leaks an ISO-3166 alpha-2 code
- /accuracy/ meta description must be 155–160 chars (got ${len
- FAQ count must be 8-12, got ' + faqs.length
- H2 "' + merged.heading + '" has no following prose
AI-assisted analysis of koala73/worldmonitor@7d06c8633d (2026-09-15).
Data as JSON: /api/errors/0036b96f53536c14.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/build-comparison-pages.mjs:731
throw new Error(label + ' meta description must be 90-160 chars (got ' + length + ')');
}
}
/**
* One `[title](url): description` entry per /compare/ route for llms.txt and
* llms-full.txt (#7746). Titles are the page h1 — the query the page answers,
* which is the string an engine matches — and descriptions are each page's
* hand-written `summary`, so the discovery index cannot drift from the pages.
*/
export function comparisonDiscoveryEntries(baseUrl) {
const hub = {
title: COMPARE_HUB_TITLE,
url: new URL(COMPARE_HUB_PATH, baseUrl).href,
description: COMPARE_HUB_DESCRIPTION,
};
const pages = COMPARISON_PAGES.map((page) => {
if (typeof page.summary !== 'string' || page.summary.trim() === '') {
throw new Error(page.slug + ' needs a summary for the llms.txt Comparisons section');
}
return { title: page.h1, url: new URL(page.path, baseUrl).href, description: page.summary };
});
return [hub, ...pages];
}
function renderCompareHub({ tpl, baseUrl, lastmod, snapshotDate }) {
const { escapeHtml, breadcrumbLd, pageDocument } = tpl;
const path = COMPARE_HUB_PATH;
const description = COMPARE_HUB_DESCRIPTION;
assertMetaDescription(description, 'compare hub');
const cards = COMPARISON_PAGES
.map((page) => ' <a class="card" href="' + escapeHtml(page.path) + '"><strong>' + escapeHtml(page.h1) + '</strong><br><span>' + escapeHtml(page.claim) + '</span></a>')
.join('\n');
const body = [
' <p class="eyebrow">Compare</p>',
' <h1>Compare World Monitor</h1>',
' <p class="lede">' + escapeHtml(COMPARE_HUB_NARRATIVE.lede) + '</p>',View on GitHub (pinned to 7d06c8633d)