affaan-m/ECC · error

Install module has unsupported targets

Error message

Install module ${moduleId} has unsupported targets: ${unsupportedTargets.join(', ')}

What it means

Thrown by readModuleTargetsOrThrow when a module's targets array contains entries that are valid non-empty strings but are not in SUPPORTED_INSTALL_TARGETS. The loader lists the offending target ids in the message so the manifest author can correct them. It runs only after the emptiness check passes.

Solutions

  1. Read the listed unsupported target ids from the error message and locate the module in manifests/install-modules.json.
  2. Replace each unsupported id with the correct value from SUPPORTED_INSTALL_TARGETS (check scripts/lib/install-manifests.js for the current list).
  3. If the target should legitimately exist, add it to SUPPORTED_INSTALL_TARGETS in scripts/lib/install-manifests.js and update install logic/tests.
  4. Regenerate the catalog (npm run catalog:sync) if module/target wiring changed.
  5. Re-run loadInstallManifests to verify.

Example fix

// before (install-modules.json)
"targets": ["claudecode", "cursor"]

// after
"targets": ["claude-code", "cursor"]
Defensive patterns

Strategy: validation

Validate before calling

const { SUPPORTED_INSTALL_TARGETS } = require('./scripts/lib/install-manifests');
const bad = moduleConfig.targets.filter(t => !SUPPORTED_INSTALL_TARGETS.includes(t.trim()));
if (bad.length) throw new Error(`Unsupported targets: ${bad.join(', ')}`);

Type guard

function usesOnlySupportedTargets(targets, supported) {
  return Array.isArray(targets) &&
    targets.every(t => typeof t === 'string' && supported.includes(t.trim()));
}

Prevention

When it happens

Trigger: loadInstallManifests() or supportsTarget() reading install-modules.json where a module declares targets with ids not present in SUPPORTED_INSTALL_TARGETS, e.g. "targets": ["claudecode"] instead of "claude-code", or "vscode" when unsupported.

Common situations: Typo in a target id after renaming targets; a new target added to a module before it was registered in SUPPORTED_INSTALL_TARGETS; following outdated docs that reference removed target names; adding a module copied from a fork with different target 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/baee7174a27469cb. Report an issue: GitHub.

Appendix: source

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

function readModuleTargetsOrThrow(module) {
  const moduleId = module && module.id ? module.id : '<unknown>';
  const targets = module && module.targets;

  if (!Array.isArray(targets)) {
    throw new Error(`Install module ${moduleId} has invalid targets; expected an array of supported target ids`);
  }

  const normalizedTargets = targets.map(target => (
    typeof target === 'string' ? target.trim() : ''
  ));

  if (normalizedTargets.some(target => target.length === 0)) {
    throw new Error(`Install module ${moduleId} has invalid targets; expected an array of supported target ids`);
  }

  const unsupportedTargets = normalizedTargets.filter(target => !SUPPORTED_INSTALL_TARGETS.includes(target));
  if (unsupportedTargets.length > 0) {
    throw new Error(
      `Install module ${moduleId} has unsupported targets: ${unsupportedTargets.join(', ')}`
    );
  }

  return normalizedTargets;
}

function assertKnownModuleIds(moduleIds, manifests) {
  const unknownModuleIds = dedupeStrings(moduleIds)
    .filter(moduleId => !manifests.modulesById.has(moduleId));

  if (unknownModuleIds.length === 1) {
    throw new Error(`Unknown install module: ${unknownModuleIds[0]}`);
  }

  if (unknownModuleIds.length > 1) {
    throw new Error(`Unknown install modules: ${unknownModuleIds.join(', ')}`);
  }

View on GitHub (pinned to 8321021c54)