affaan-m/ECC · error · Error

Unknown install target: ${target}. Expected one of ${SUPPORT

Error message

Unknown install target: ${target}. Expected one of ${SUPPORTED_INSTALL_TARGETS.join(', ')}

What it means

Thrown by validateLegacyTarget() when the target is neither in LEGACY_INSTALL_TARGETS nor in SUPPORTED_INSTALL_TARGETS — i.e. genuinely unknown. The message lists every supported target so the user can pick a valid one.

Source

Thrown at scripts/lib/install-executor.js:80

function listAvailableLanguages(sourceRoot = getSourceRoot()) {
  return [...new Set([...listLegacyCompatibilityLanguages(), ...readDirectoryNames(path.join(sourceRoot, 'rules')).filter(name => name !== 'common')])].sort();
}

function validateLegacyTarget(target) {
  if (LEGACY_INSTALL_TARGETS.includes(target)) {
    return;
  }
  // A target can be fully supported yet not installable via the bare-language
  // positional syntax (which is legacy-only). Guide the user to the right mode
  // instead of implying the target is unknown (#2282).
  if (SUPPORTED_INSTALL_TARGETS.includes(target)) {
    throw new Error(
      `Target '${target}' is supported, but the bare-language install syntax only accepts ${LEGACY_INSTALL_TARGETS.join(', ')}. ` +
        `Install '${target}' with a component selection instead, e.g. \`install.sh --target ${target} --profile full\` ` +
        `(or --modules <id,...> / --skills <id,...>).`
    );
  }
  throw new Error(`Unknown install target: ${target}. Expected one of ${SUPPORTED_INSTALL_TARGETS.join(', ')}`);
}

const IGNORED_DIRECTORY_NAMES = new Set(['node_modules', '.git']);

function listFilesRecursive(dirPath) {
  if (!fs.existsSync(dirPath)) {
    return [];
  }

  const files = [];
  const entries = fs.readdirSync(dirPath, { withFileTypes: true });

  for (const entry of entries) {
    const absolutePath = path.join(dirPath, entry.name);
    if (entry.isDirectory()) {
      if (IGNORED_DIRECTORY_NAMES.has(entry.name)) {
        continue;
      }

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Compare against the list in the error message and correct the spelling/casing.
  2. Run the install with --target to see the same validation set, or list targets programmatically: console.log(require('./install-manifests').SUPPORTED_INSTALL_TARGETS).
  3. Trim whitespace from the positional argument before passing.

Example fix

# before
./install.sh claudeproj

# after
./install.sh claude-project
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED = ['claude','claude-project','cursor','antigravity','codex','gemini','opencode','codebuddy','joycode','qwen','zed','hermes','openclaw','kimi'];
function isSupportedTarget(t) {
  return typeof t === 'string' && SUPPORTED.includes(t.trim());
}
if (!isSupportedTarget(target)) {
  throw new Error(`Unsupported target '${target}'. Supported: ${SUPPORTED.join(', ')}`);
}

Type guard

function isInstallTarget(v) {
  return typeof v === 'string'
    && ['claude','claude-project','cursor','antigravity','codex','gemini','opencode','codebuddy','joycode','qwen','zed','hermes','openclaw','kimi'].includes(v.trim());
}

Try / catch

try {
  validateLegacyTarget(target);
} catch (err) {
  if (/Unknown install target/.test(err.message)) {
    throw new Error(`${err.message}. Run with --list-targets to see options.`);
  }
  throw err;
}

Prevention

When it happens

Trigger: validateLegacyTarget('foo'), validateLegacyTarget(''), or any typo that does not appear in SUPPORTED_INSTALL_TARGETS = [claude, claude-project, cursor, antigravity, codex, gemini, opencode, codebuddy, joycode, qwen, zed, hermes, openclaw, kimi].

Common situations: Typo (e.g. 'claudeproj' instead of 'claude-project'); stale docs naming a removed target; user invents a harness name; trailing whitespace or wrong casing in the positional argument.

Related errors


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