affaan-m/ECC · error · Error

Unknown install target adapter: ${targetOrAdapterId}

Error message

Unknown install target adapter: ${targetOrAdapterId}

What it means

Thrown by getInstallTargetAdapter in scripts/lib/install-targets/registry.js when no registered adapter's supports(target) returns true. supports() matches only exact-string equality with the adapter's target or id field. The registered set is fixed at module load (claude, claude-project, cursor, antigravity, codex, gemini, hermes, opencode, openclaw, codebuddy, joycode, kimi, qwen, zed). Any other string — including a target with different casing, a hyphenated id where the target is wanted, or an unsupported harness name — throws.

Source

Thrown at scripts/lib/install-targets/registry.js:41

  hermesHome,
  opencodeHome,
  openclawHome,
  codebuddyProject,
  joycodeProject,
  kimiProject,
  qwenHome,
  zedProject,
]);

function listInstallTargetAdapters() {
  return ADAPTERS.slice();
}

function getInstallTargetAdapter(targetOrAdapterId) {
  const adapter = ADAPTERS.find(candidate => candidate.supports(targetOrAdapterId));

  if (!adapter) {
    throw new Error(`Unknown install target adapter: ${targetOrAdapterId}`);
  }

  return adapter;
}

function planInstallTargetScaffold(options = {}) {
  const adapter = getInstallTargetAdapter(options.target);
  const modules = Array.isArray(options.modules) ? options.modules : [];
  const exemptValidationCodes = new Set(Array.isArray(options.exemptValidationCodes) ? options.exemptValidationCodes : []);
  const planningInput = {
    repoRoot: options.repoRoot,
    projectRoot: options.projectRoot || options.repoRoot,
    homeDir: options.homeDir,
  };
  const validationIssues = adapter.validate(planningInput);
  const blockingIssues = validationIssues.filter(issue => (
    issue.severity === 'error' && !exemptValidationCodes.has(issue.code)
  ));

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Call listInstallTargetAdapters() and print each adapter's target and id to see the exact supported strings.
  2. Use the canonical target string (e.g. 'kimi', not the id 'kimi-project').
  3. If you genuinely need a new target, write a new adapter module, register it in the ADAPTERS array in registry.js, and ensure its supports() accepts the string you pass.

Example fix

// before
planInstallTargetScaffold({ target: 'kimi-project', modules });

// after
planInstallTargetScaffold({ target: 'kimi', modules });
Defensive patterns

Strategy: validation

Validate before calling

const { listInstallTargetAdapters } = require('./registry');
const VALID = new Set(
  listInstallTargetAdapters().flatMap(a => [a.target, a.id])
);
if (!VALID.has(userTarget)) {
  throw new Error(
    `Unsupported target '${userTarget}'. Valid: ${[...VALID].join(', ')}`
  );
}

Type guard

const VALID_TARGETS = new Set([
  'claude','claude-project','cursor','antigravity','codex','gemini',
  'hermes','opencode','openclaw','codebuddy','joycode','kimi','qwen','zed'
]);
function isInstallTarget(value) {
  return typeof value === 'string' && VALID_TARGETS.has(value);
}

Try / catch

try {
  getInstallTargetAdapter(target);
} catch (err) {
  if (/Unknown install target adapter/.test(err.message)) {
    console.error('Valid targets:', listInstallTargetAdapters().map(a => a.target).join(', '));
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling planInstallTargetScaffold({ target: 'kimi-project' }) (adapter id, not target), getInstallTargetAdapter('vscode'), or passing a camelCase variant like 'claudeCode'.

Common situations: Misspelling or wrong casing ('Cl ude', 'Kimi'); confusing adapter.id with adapter.target; version drift after a target rename; assuming a harness ECC never supported.

Related errors


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