affaan-m/ECC · error · Error

Install module ${moduleId} has invalid targets; expected an

Error message

Install module ${moduleId} has invalid targets; expected an array of supported target ids

What it means

readModuleTargetsOrThrow reads `module.targets` from install-modules.json. The field MUST be an array; anything else (string, object, null, undefined, number) is rejected up front. The check fires before any per-element validation, so this is specifically the wrong-shape failure.

Source

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

    || options[key] === null
    || options[key] === undefined
  ) {
    return null;
  }

  if (typeof options[key] !== 'string' || options[key].trim() === '') {
    throw new Error(`${key} must be a non-empty string when provided`);
  }

  return options[key];
}

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;

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Open manifests/install-modules.json and find the module whose id appears in the error.
  2. Change `targets` to an array: `"targets": ["claude"]` (not `"targets": "claude"`).
  3. Validate the file against the manifest schema before committing (`npm run catalog:sync` or the project's manifest validator).
  4. Re-run `npm test` to catch manifest shape errors locally.

Example fix

// before: { "id": "rules-core", "targets": "claude" }
// after: { "id": "rules-core", "targets": ["claude"] }
Defensive patterns

Strategy: validation

Validate before calling

function moduleHasArrayTargets(module) {
  return Boolean(module && Array.isArray(module.targets));
}
// when loading manifests: manifests.modules.every(moduleHasArrayTargets)

Type guard

function isModuleWithArrayTargets(module) {
  return Boolean(module && typeof module === 'object' && Array.isArray(module.targets));
}

Try / catch

try {
  loadInstallManifests({ repoRoot });
} catch (err) {
  if (/has invalid targets; expected an array/.test(err.message)) {
    // fix the manifest entry by id, then retry
  } else throw err;
}

Prevention

When it happens

Trigger: loadInstallManifests parses install-modules.json and an entry has `targets` as a string ('claude') or an object instead of `['claude']`. Triggered at load time for any code path that reads modules (resolveInstallModules, intersectTargets, listInstallComponents).

Common situations: Manifest hand-edited and the author wrote a scalar instead of an array; YAML-to-JSON converter collapsed a single-item array to a scalar; schema-validation disabled in CI; copy-paste from docs that showed shorthand syntax.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/4427bbe3af5f54b4. Report an issue: GitHub.