{"record":{"id":"8cde76ec1542f1a1","repo":"koala73/worldmonitor","slug":"needs-a-world-monitor-measurement-explanation","errorCode":null,"errorMessage":" needs a World Monitor measurement explanation","messagePattern":" needs a World Monitor measurement explanation","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/build-comparison-pages.mjs","lineNumber":583,"sourceCode":"    '@type': 'WebPage',\n    '@id': url + '#webpage',\n    name,\n    description,\n    url,\n    inLanguage: 'en-US',\n    dateModified: lastmod,\n    isPartOf: { '@id': new URL('/#website', baseUrl).href },\n    breadcrumb: { '@id': url + '#breadcrumb' },\n    mainEntity: { '@id': faqId },\n  };\n}\n\nfunction renderMeasurement(slug, snapshotDate, escapeHtml) {\n  if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(snapshotDate ?? '')) {\n    throw new Error('Comparison measurement requires the captured snapshot date');\n  }\n  const paragraphs = COMPARISON_MEASUREMENTS[slug];\n  if (!paragraphs?.length) throw new Error(slug + ' needs a World Monitor measurement explanation');\n  const maritime = slug === 'chokepoint-monitoring-tools';\n  const snapshotPath = maritime ? '/chokepoints/status.json' : '/country-instability-index/cii-ranking.json';\n  return [\n    '      <h2>How World Monitor measures this</h2>',\n    ...renderParagraphs(paragraphs, escapeHtml),\n    '      <p>Coverage: the <a href=\"/sources/\">source catalog</a> lists ' + escapeHtml(formatCount(WORLD_MONITOR_PROVIDER_COUNT)) + ' active providers across the product, not per metric. Availability varies by source and location.</p>',\n    '      <p data-measurement-snapshot><a href=\"' + snapshotPath + '\">Published ' + (maritime ? 'chokepoint status' : 'country instability') + ' snapshot</a>, captured <time datetime=\"' + escapeHtml(snapshotDate) + '\">' + escapeHtml(snapshotDate) + '</time>. This reference remains dated when live values change.</p>',\n  ];\n}\n\nfunction renderComparePage(page, { tpl, baseUrl, lastmod, snapshotDate }) {\n  const { escapeHtml, breadcrumbLd, pageDocument } = tpl;\n  const pageUrl = new URL(page.path, baseUrl).href;\n  const description = page.metaDescription ?? (page.h1\n    + ' - ' + page.claim\n    + '. Full comparison matrix, honest concessions, and FAQs.');\n  assertMetaDescription(description, page.slug);\n","sourceCodeStart":565,"sourceCodeEnd":601,"githubUrl":"https://github.com/koala73/worldmonitor/blob/7d06c8633d256c18e38133030bc3613976a96ec9/scripts/build-comparison-pages.mjs#L565-L601","documentation":"After validating the snapshot date, renderMeasurement looks up COMPARISON_MEASUREMENTS[slug] for the page's 'How World Monitor measures this' paragraphs. Every comparison slug must have a measurement explanation; if the map has no entry (or an empty array), the build throws '<slug> needs a World Monitor measurement explanation'.","triggerScenarios":"Adding a new slug to COMPARISON_PAGE_SEEDS without adding a matching key in COMPARISON_MEASUREMENTS, or an entry whose value is [] — renderMeasurement then finds paragraphs?.length falsy.","commonSituations":"New comparison page added; slug renamed in the seeds but not in COMPARISON_MEASUREMENTS (typo or rebrand); measurement content removed pending rewrite, leaving an empty array.","solutions":["Add a COMPARISON_MEASUREMENTS entry keyed by the exact slug with at least one paragraph string.","If the slug was renamed, rename the COMPARISON_MEASUREMENTS key to match the seed slug.","Restore the deleted/emptied measurement paragraphs for that slug."],"exampleFix":"// before\nconst COMPARISON_MEASUREMENTS = {\n  'chokepoint-monitoring-tools': [...],\n};\n// after\nconst COMPARISON_MEASUREMENTS = {\n  'chokepoint-monitoring-tools': [...],\n  'country-instability-index-alternatives': [\n    'World Monitor computes the Country Instability Index from ...',\n  ],\n};","handlingStrategy":"validation","validationCode":"const missing = COMPARISON_PAGE_SEEDS.filter((s) => !(COMPARISON_MEASUREMENTS[s.slug]?.length));\nif (missing.length) throw new Error(`slugs missing measurement prose: ${missing.map((s) => s.slug).join(', ')}`);\n","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat COMPARISON_PAGE_SEEDS and COMPARISON_MEASUREMENTS as one unit: update both in the same commit.","Add a build-time test asserting seed slugs and measurement keys match exactly."],"tags":["build","content-validation","missing-content","comparison-pages"],"backgroundTag":"missing-config-value","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"}