affaan-m/ECC · error

Unknown legacy language

Error message

Unknown legacy language: ${unknownLegacyLanguages[0]}. Expected one of ${listLegacyCompatibilityLanguages().join(', ')}

What it means

Each normalized legacy language must be a key of LEGACY_LANGUAGE_ALIAS_TO_CANONICAL. When exactly one unknown language remains after filtering, the function throws naming it and listing the accepted values from listLegacyCompatibilityLanguages().

Solutions

  1. Use one of the accepted values/aliases listed in the error message
  2. Check LEGACY_LANGUAGE_ALIAS_TO_CANONICAL in install-manifests.js for the exact alias set
  3. Normalize user input against the alias map before calling

Example fix

// before
resolveLegacyCompatibilitySelection({ legacyLanguages: ['pythn'] })
// after
resolveLegacyCompatibilitySelection({ legacyLanguages: ['python'] })
Defensive patterns

Strategy: validation

Validate before calling

const accepted = new Set(Object.keys(LEGACY_LANGUAGE_ALIAS_TO_CANONICAL));
const bad = options.legacyLanguages.filter(l => !accepted.has(String(l).toLowerCase()));
if (bad.length === 1) throw new Error(`unknown legacy language: ${bad[0]}`);

Type guard

function isKnownLegacyLanguage(l) {
  return typeof l === 'string' && Object.hasOwn(LEGACY_LANGUAGE_ALIAS_TO_CANONICAL, l.toLowerCase());
}

Try / catch

try {
  const sel = resolveLegacyCompatibilitySelection(options);
} catch (err) {
  if (err.message.startsWith('Unknown legacy language:')) {
    console.error(`${err.message}`); process.exitCode = 2;
  } else throw err;
}

Prevention

When it happens

Trigger: resolveLegacyCompatibilitySelection({ legacyLanguages: ['pythn'] }) — a single unrecognized language string (note: it is lowercased before the check, so case alone will not trigger it).

Common situations: Typos in language names, using full names like 'typescript' when only aliases are supported, or passing values from another tool's vocabulary.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/ad89add030b1b7f0. Report an issue: GitHub.

Appendix: source

Thrown at scripts/lib/install-manifests.js:510

  if (target && !SUPPORTED_INSTALL_TARGETS.includes(target)) {
    throw new Error(
      `Unknown install target: ${target}. Expected one of ${SUPPORTED_INSTALL_TARGETS.join(', ')}`
    );
  }

  const legacyLanguages = dedupeStrings(options.legacyLanguages)
    .map(language => language.toLowerCase());
  const normalizedLegacyLanguages = dedupeStrings(legacyLanguages);

  if (normalizedLegacyLanguages.length === 0) {
    throw new Error('No legacy languages were provided');
  }

  const unknownLegacyLanguages = normalizedLegacyLanguages
    .filter(language => !Object.hasOwn(LEGACY_LANGUAGE_ALIAS_TO_CANONICAL, language));

  if (unknownLegacyLanguages.length === 1) {
    throw new Error(
      `Unknown legacy language: ${unknownLegacyLanguages[0]}. Expected one of ${listLegacyCompatibilityLanguages().join(', ')}`
    );
  }

  if (unknownLegacyLanguages.length > 1) {
    throw new Error(
      `Unknown legacy languages: ${unknownLegacyLanguages.join(', ')}. Expected one of ${listLegacyCompatibilityLanguages().join(', ')}`
    );
  }

  const canonicalLegacyLanguages = normalizedLegacyLanguages
    .map(language => LEGACY_LANGUAGE_ALIAS_TO_CANONICAL[language]);
  const ruleLanguages = normalizedLegacyLanguages.map(language => (
    LEGACY_LANGUAGE_RULE_NAMESPACES[language] || language
  ));
  const baseModuleIds = LEGACY_COMPAT_BASE_MODULE_IDS_BY_TARGET[target || 'claude']
    || LEGACY_COMPAT_BASE_MODULE_IDS_BY_TARGET.claude;
  const moduleIds = dedupeStrings([

View on GitHub (pinned to 8321021c54)