{"record":{"id":"0036b96f53536c14","repo":"koala73/worldmonitor","slug":"needs-a-summary-for-the-llms-txt-comparisons-section","errorCode":null,"errorMessage":" needs a summary for the llms.txt Comparisons section","messagePattern":" needs a summary for the llms\\.txt Comparisons section","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/build-comparison-pages.mjs","lineNumber":731,"sourceCode":"    throw new Error(label + ' meta description must be 90-160 chars (got ' + length + ')');\n  }\n}\n\n/**\n * One `[title](url): description` entry per /compare/ route for llms.txt and\n * llms-full.txt (#7746). Titles are the page h1 — the query the page answers,\n * which is the string an engine matches — and descriptions are each page's\n * hand-written `summary`, so the discovery index cannot drift from the pages.\n */\nexport function comparisonDiscoveryEntries(baseUrl) {\n  const hub = {\n    title: COMPARE_HUB_TITLE,\n    url: new URL(COMPARE_HUB_PATH, baseUrl).href,\n    description: COMPARE_HUB_DESCRIPTION,\n  };\n  const pages = COMPARISON_PAGES.map((page) => {\n    if (typeof page.summary !== 'string' || page.summary.trim() === '') {\n      throw new Error(page.slug + ' needs a summary for the llms.txt Comparisons section');\n    }\n    return { title: page.h1, url: new URL(page.path, baseUrl).href, description: page.summary };\n  });\n  return [hub, ...pages];\n}\n\nfunction renderCompareHub({ tpl, baseUrl, lastmod, snapshotDate }) {\n  const { escapeHtml, breadcrumbLd, pageDocument } = tpl;\n  const path = COMPARE_HUB_PATH;\n  const description = COMPARE_HUB_DESCRIPTION;\n  assertMetaDescription(description, 'compare hub');\n  const cards = COMPARISON_PAGES\n    .map((page) => '        <a class=\"card\" href=\"' + escapeHtml(page.path) + '\"><strong>' + escapeHtml(page.h1) + '</strong><br><span>' + escapeHtml(page.claim) + '</span></a>')\n    .join('\\n');\n  const body = [\n    '      <p class=\"eyebrow\">Compare</p>',\n    '      <h1>Compare World Monitor</h1>',\n    '      <p class=\"lede\">' + escapeHtml(COMPARE_HUB_NARRATIVE.lede) + '</p>',","sourceCodeStart":713,"sourceCodeEnd":749,"githubUrl":"https://github.com/koala73/worldmonitor/blob/7d06c8633d256c18e38133030bc3613976a96ec9/scripts/build-comparison-pages.mjs#L713-L749","documentation":"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'.","triggerScenarios":"Mapping COMPARISON_PAGES in comparisonDiscoveryEntries when a page's summary is undefined, not a string, an empty string, or whitespace-only (summary.trim() === '').","commonSituations":"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.","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."],"exampleFix":"// before\n{\n  slug: 'chokepoint-monitoring-tools',\n  // no summary\n}\n// after\n{\n  slug: 'chokepoint-monitoring-tools',\n  summary: 'Compare the leading chokepoint monitoring tools and how World Monitor tracks maritime chokepoints in real time.',\n}","handlingStrategy":"validation","validationCode":"COMPARISON_PAGES.forEach((p) => {\n  if (typeof p.summary !== 'string' || !p.summary.trim()) throw new Error(`${p.slug} missing summary`);\n});","typeGuard":"const hasSummary = (p) => typeof p?.summary === 'string' && p.summary.trim() !== '';","tryCatchPattern":null,"preventionTips":["Include summary in the seed template/checklist for new comparison pages.","Never use empty-string placeholders for summary in committed seeds."],"tags":["build","seo","content-validation","llms-txt"],"backgroundTag":"empty-required-field","analyzedSha":"7d06c8633d256c18e38133030bc3613976a96ec9","analyzedAt":"2026-09-15T16:44:39.439Z","contentChangedAt":"2026-09-15T16:44:39.439Z","schemaVersion":2},"datasetVersion":"2026-09-15T18:17:12.389Z"}