koala73/worldmonitor · error · Error

${chokepoint.id}: ${field} must be an array

Error message

${chokepoint.id}: ${field} must be an array

What it means

Inside buildChokepointPageLinks(), the resolve() helper reads declaration[field] for 'countryCodes' and 'crisisSlugs' and requires an array of ids. This throw fires when one of those relation fields is present but not an array (e.g. a single string code). Like the other checks in this function it is a fail-fast build-time validation that stops malformed chokepoint relation data from reaching generated pages.

Solutions

  1. Change the field in the chokepoint declaration to an array of string ids, e.g. countryCodes: ['US','IR'] or crisisSlugs: ['red-sea-crisis'].
  2. If the value arrives as a delimited string from an external source, coerce before the call: Array.isArray(v) ? v : String(v).split(',').
  3. Add a schema validation step over content declarations so wrong shapes surface before the build.

Example fix

// before
countryCodes: 'YE'
// after
countryCodes: ['YE']
Defensive patterns

Strategy: validation

Validate before calling

for (const field of ['countryCodes', 'crisisSlugs']) {
  const v = content[chokepoint.id]?.[field];
  if (v != null && !Array.isArray(v)) throw new TypeError(`${chokepoint.id}: ${field} must be an array`);
}

Type guard

const isIdArray = (v) => v == null || (Array.isArray(v) && v.every((id) => typeof id === 'string'));

Prevention

When it happens

Trigger: content[chokepoint.id].countryCodes or content[chokepoint.id].crisisSlugs is a non-nullish non-array value (string, object, number) when buildChokepointPageLinks() iterates that chokepoint.

Common situations: Author writes countryCodes: 'YE' instead of ['YE']; a YAML/JSON loader returns a comma-separated string; a merge tool collapses a single-element array into a scalar; an external data export delivers the wrong JSON type.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of koala73/worldmonitor@7d06c8633d (2026-09-15). Data as JSON: /api/errors/2aab21cf0c12be9a. Report an issue: GitHub.

Appendix: source

Thrown at scripts/build-crawlable-corpus.mjs:1382

  const countryByCode = new Map(countries.map((country) => [country.code, country]));
  const crisisBySlug = new Map(crises.map((crisis) => [crisis.slug, crisis]));
  const byChokepointId = new Map();
  const byCountryCode = new Map();
  const byCrisisSlug = new Map();
  for (const chokepoint of chokepoints) {
    const declaration = content[chokepoint.id] || {};
    const editorialLinks = declaration.editorialLinks ?? [];
    if (!Array.isArray(editorialLinks)) throw new Error(`${chokepoint.id}: editorialLinks must be an array`);
    const editorial = new Map();
    for (const link of editorialLinks) {
      if (!blogPostPaths.has(link?.href) || typeof link.label !== 'string' || !link.label.trim()) {
        throw new Error(`${chokepoint.id}: editorialLinks requires a canonical blog post path and label: ${link?.href}`);
      }
      if (!editorial.has(link.href)) editorial.set(link.href, link);
    }
    const resolve = (field, targets, inverse) => {
      const ids = declaration[field] ?? [];
      if (!Array.isArray(ids)) throw new Error(`${chokepoint.id}: ${field} must be an array`);
      return [...new Set(ids)].map((id) => {
        const target = targets.get(id);
        if (!target) throw new Error(`${chokepoint.id}: ${field} contains unknown target ${id}`);
        const entries = inverse.get(id) || [];
        entries.push(chokepoint);
        inverse.set(id, entries);
        return target;
      });
    };
    byChokepointId.set(chokepoint.id, {
      countries: resolve('countryCodes', countryByCode, byCountryCode),
      crises: resolve('crisisSlugs', crisisBySlug, byCrisisSlug),
      editorial: [...editorial.values()],
    });
  }
  return { byChokepointId, byCountryCode, byCrisisSlug };
}

View on GitHub (pinned to 7d06c8633d)