koala73/worldmonitor · error
is missing the switch-trigger section
Error message
is missing the switch-trigger section
What it means
applyComparisonNarrative requires a switch-trigger section on every comparison page: a truthy switchHeading plus a non-empty switchProse array. This section explains when a reader should switch tools; it is mandatory and its absence fails the build.
Solutions
- Add switchHeading and a non-empty switchProse array to the slug's narrative entry.
- Author honest 'choose X when...' content for the section.
- Check field spelling against a passing narrative.
- Re-add prose if it was removed in a recent copy edit (git diff the narrative map).
Example fix
// before
'worldmonitor-vs-x': { evaluationHeading: 'How we evaluated', evaluationProse: [...] }
// after
'worldmonitor-vs-x': {
evaluationHeading: 'How we evaluated',
evaluationProse: [...],
switchHeading: 'When to switch',
switchProse: ['Switch to Flightradar24 only if you need ADS-B playback history beyond 30 days.'],
} Defensive patterns
Strategy: validation
Validate before calling
if (!narrative.switchHeading || !narrative.switchProse?.length) {
throw new Error(page.slug + ' missing switch-trigger section');
} Type guard
const hasSwitchSection = (n) => typeof n.switchHeading === 'string' && n.switchHeading.trim() !== '' && Array.isArray(n.switchProse) && n.switchProse.length > 0;
Try / catch
try {
page = applyComparisonNarrative(page);
} catch (e) {
if (String(e.message).includes('missing the switch-trigger section')) {
console.error('Add switchHeading + switchProse for:', e.message);
} else throw e;
} Prevention
- Include switchHeading/switchProse in the narrative starter template.
- Validate all mandatory narrative fields in one pre-build audit instead of one throw at a time.
- When removing prose in copy edits, check git diff for emptied required arrays.
When it happens
Trigger: Running the build when a slug's merged narrative lacks switchHeading or has an empty/missing switchProse array.
Common situations: Omitting the section when authoring a new narrative from scratch; a copy pass deleting the prose but leaving the heading; misspelled field names (switchTriggerProse instead of switchProse).
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
- Missing comparison narrative for ' + page.slug
- is missing whyWeWinBody
- is missing the evaluation section
- /accuracy/ meta description must be 155–160 chars (got ${len
- FAQ count must be 8-12, got ' + faqs.length
AI-assisted analysis of koala73/worldmonitor@7d06c8633d (2026-09-15).
Data as JSON: /api/errors/b444e17fbcd085c5.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/build-comparison-pages.mjs:477
faqNames.add(key);
}
const merged = { ...page, ...narrative, faqs };
delete merged.extraFaqs;
const whyBody = (merged.whyWeWinBody ?? []).join(' ').replace(/\s+/g, ' ').trim();
if (!whyBody) {
throw new Error(page.slug + ' is missing whyWeWinBody');
}
if (whyBody === merged.whyWeWin.replace(/\s+/g, ' ').trim()) {
throw new Error(page.slug + ' whyWeWinBody must not repeat whyWeWin');
}
if (merged.heading && !(merged.headingProse?.length || merged.competitorProfiles?.length)) {
throw new Error(page.slug + ' H2 "' + merged.heading + '" has no following prose');
}
if (!merged.evaluationHeading || !merged.evaluationProse?.length) {
throw new Error(page.slug + ' is missing the evaluation section');
}
if (!merged.switchHeading || !merged.switchProse?.length) {
throw new Error(page.slug + ' is missing the switch-trigger section');
}
if (!merged.methodologyProse?.length) {
throw new Error(page.slug + ' is missing methodology prose');
}
return merged;
}
export const COMPARISON_PAGES = COMPARISON_PAGE_SEEDS.map(applyComparisonNarrative);
function renderParagraphs(paragraphs, escapeHtml) {
return (paragraphs ?? []).map((paragraph) => ' <p>' + escapeHtml(paragraph) + '</p>');
}
function renderHeadingSection(heading, paragraphs, escapeHtml, label) {
if (!heading) return [];
const body = renderParagraphs(paragraphs, escapeHtml);
if (body.length === 0) {
throw new Error((label || heading) + ' is missing following prose');View on GitHub (pinned to 7d06c8633d)