affaan-m/ECC · error · Error

Choose at least one guided harness: Claude, Codex, or Kimi.

Error message

Choose at least one guided harness: Claude, Codex, or Kimi.

What it means

normalizeGuidedInstallRequest validates the guided multi-harness install request. It normalizes the harnesses selection, and if the resulting list is empty it throws this error — a guided install must target at least one of the supported harnesses (Claude, Codex, Kimi).

Solutions

  1. Pass at least one supported harness, e.g. harnesses: ['claude'].
  2. Check spelling of harness names (claude, codex, kimi) — invalid entries are normalized away.
  3. If running the CLI, add the required harness flag/option to the command.
  4. Re-run the interactive flow and select at least one harness before confirming.

Example fix

// before
request({ harnesses: [] });
// after
request({ harnesses: ['claude', 'codex'] });
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED = ['claude', 'codex', 'kimi'];
const harnesses = (input.harnesses || []).filter(h => SUPPORTED.includes(h));
if (harnesses.length === 0) throw new Error('Select at least one of: claude, codex, kimi.');

Type guard

const hasValidHarnessSelection = (input) => Array.isArray(input.harnesses) && input.harnesses.some(h => ['claude','codex','kimi'].includes(h));

Try / catch

try {
  normalizeGuidedInstallRequest(input);
} catch (err) {
  if (err.message.includes('Choose at least one guided harness')) {
    // prompt the user again or default to ['claude']
  } else throw err;
}

Prevention

When it happens

Trigger: Invoking the guided setup/request path with harnesses omitted, an empty array, or a list whose entries all fail normalization (invalid names dropped) — e.g. input.harnesses = [] or input.harnesses = ['cursor'] (unsupported in guided mode).

Common situations: CLI invocation missing the harness flag; config file with a misspelled harness name that normalizes away; interactive flow where the user unchecked every option before submitting.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at scripts/lib/multi-harness-setup.js:23

const os = require('os');
const path = require('path');

const { assertSafeInstallOperation } = require('./install/apply');
const { assertWithinTrustedRoot, realpathNearestExisting } = require('./path-safety');

const VALID_CLAUDE_SCOPES = new Set(['user', 'project', 'local']);
const VALID_CLAUDE_HOOKS = new Set(['off', 'minimal', 'standard', 'strict']);
const VALID_PROFILES = new Set(['minimal', 'core', 'developer', 'security', 'research', 'full']);

function catalogHelpers() {
  return require('./harness-capabilities');
}

function normalizeGuidedInstallRequest(input = {}) {
  const { normalizeHarnessSelection } = catalogHelpers();
  const harnesses = normalizeHarnessSelection(input.harnesses || []);
  if (harnesses.length === 0) {
    throw new Error('Choose at least one guided harness: Claude, Codex, or Kimi.');
  }

  const includesClaude = harnesses.includes('claude');
  const includesKimi = harnesses.includes('kimi');
  if (!includesClaude && (input.claudeScope !== undefined || input.claudeHooks !== undefined)) {
    throw new Error('Claude scope and hook options require Claude to be selected.');
  }
  if (!includesKimi && input.profile !== undefined) {
    throw new Error('The managed install profile requires Kimi to be selected.');
  }

  const claudeScope = includesClaude ? (input.claudeScope || 'user') : undefined;
  const claudeHooks = includesClaude ? (input.claudeHooks || 'standard') : undefined;
  const profile = includesKimi ? (input.profile || 'core') : undefined;
  if (claudeScope && !VALID_CLAUDE_SCOPES.has(claudeScope)) {
    throw new Error(`Invalid Claude scope: ${claudeScope}`);
  }
  if (claudeHooks && !VALID_CLAUDE_HOOKS.has(claudeHooks)) {

View on GitHub (pinned to 8321021c54)