koala73/worldmonitor · error · Error

Source card anchor collision: ${JSON.stringify(seen.get(anch

Error message

Source card anchor collision: ${JSON.stringify(seen.get(anchor))} and ${JSON.stringify(provider.provider)} both map to #${anchor}

What it means

sourceCardAnchors builds a deterministic DOM anchor for each provider card as provider-<slug>-<sha1-prefix>. It throws when two distinct provider names hash/slug to the same anchor, because two cards sharing an id would break linking and duplicate-id validity. Note the guard: if the same provider name repeats, it is tolerated; only genuinely different providers colliding on one anchor throw.

Solutions

  1. Find the two colliding provider names in the error message and rename one so its slugged form is distinct.
  2. Review slugBase normalization; if it strips distinguishing characters, adjust the provider name or the slug function.
  3. Add a catalog lint/test that runs sourceCardAnchors over sourceCatalog to catch collisions before deploy.

Example fix

// before
{ provider: 'acme inc' }, { provider: 'Acme, Inc.' } // same anchor
// after
{ provider: 'acme-inc' }, { provider: 'acme-labs' }
Defensive patterns

Strategy: validation

Validate before calling

const names = sourceCatalog.map((p) => String(p.provider ?? ''));
const anchors = new Set(names.map((n) => `provider-${slugBase(n)}-${createHash('sha1').update(n).digest('hex').slice(0, 16)}`));
if (anchors.size !== new Set(names).size) throw new Error('provider anchor collision in catalog');

Try / catch

try {
  const anchors = sourceCardAnchors(sourceCatalog);
} catch (e) {
  if (e.message.startsWith('Source card anchor collision')) {
    console.error('Rename one of the colliding providers so slugs differ.');
    process.exit(2);
  }
  throw e;
}

Prevention

When it happens

Trigger: Adding a new provider to sourceCatalog whose name differs from an existing one only in characters that slugify away or whose sha1 first-16-hex collision maps to the same key string — e.g. names differing only by case/punctuation that slugBase normalizes identically.

Common situations: Renaming a provider in a way that slugBase makes identical to another (e.g. 'Acme, Inc.' vs 'acme inc'), or duplicating a catalog entry with a slightly edited label.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at scripts/crawlable-sources-page.mjs:776

 * so the import would close a cycle. A local slug helper is also what the other
 * generators in scripts/ do.
 */
export function sourceCardAnchors(sourceCatalog) {
  const slugBase = (key) => String(key ?? '')
    .normalize('NFKD')
    .replace(/[\u0300-\u036f]/g, '')
    .replace(/&/g, ' and ')
    .replace(/[^a-zA-Z0-9]+/g, '-')
    .replace(/^-+|-+$/g, '')
    .toLowerCase() || 'source';

  const anchors = new Map();
  const seen = new Map();
  for (const provider of sourceCatalog) {
    const key = String(provider.provider ?? '');
    const anchor = `provider-${slugBase(key)}-${createHash('sha1').update(key).digest('hex').slice(0, 16)}`;
    if (seen.has(anchor) && seen.get(anchor) !== provider.provider) {
      throw new Error(
        `Source card anchor collision: ${JSON.stringify(seen.get(anchor))} and ${JSON.stringify(provider.provider)} both map to #${anchor}`,
      );
    }
    seen.set(anchor, provider.provider);
    anchors.set(provider.provider, anchor);
  }
  return anchors;
}

export function buildSourcePages(sourceCatalog) {
  return SOURCE_DOMAINS.flatMap((domain) => {
    const providers = sourceCatalog.filter((provider) => provider.domainId === domain.id);
    const pages = [];
    for (let offset = 0; offset < providers.length; offset += 60) {
      const number = offset / 60 + 1;
      pages.push({
        path: `/sources/${domain.id}/${number === 1 ? '' : `page/${number}/`}`,
        name: `${domain.name}${number === 1 ? '' : ` — page ${number}`}`,

View on GitHub (pinned to 7d06c8633d)