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 requires at least one harness to install for. It runs the raw input.harnesses through normalizeHarnessSelection (which dedupes, lowercases, and validates against the supported set); if the result is empty — either because nothing was passed or because every entry was unrecognized and filtered out — it throws. This is the top-level guard for the multi-harness installer; without a selected harness there is nothing to do.

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 01e15490f0)

Solutions

  1. Pass at least one valid harness: harnesses: ['claude'], ['codex'], ['kimi'], or any combination.
  2. Check the spelling and casing expected by normalizeHarnessSelection (typically lowercase identifiers, not display names).
  3. If driving the CLI, supply the harness flag explicitly (e.g. --harness claude).
  4. Confirm the input object shape — the function reads input.harnesses, not input.harness or input.target.

Example fix

// before
normalizeGuidedInstallRequest({}); // throws
// after
normalizeGuidedInstallRequest({ harnesses: ['claude'] });
// or multiple
normalizeGuidedInstallRequest({ harnesses: ['claude', 'kimi'] });
Defensive patterns

Strategy: validation

Validate before calling

const { normalizeHarnessSelection } = require('./scripts/lib/harness-capabilities');
function assertHasHarness(input = {}) {
  const harnesses = normalizeHarnessSelection(input.harnesses || []);
  if (harnesses.length === 0) {
    throw new Error('Choose at least one guided harness: Claude, Codex, or Kimi.');
  }
  return harnesses;
}
// before normalizeGuidedInstallRequest:
assertHasHarness(input);

Type guard

function hasHarnessSelection(input = {}) {
  return Array.isArray(input.harnesses) && input.harnesses.length > 0;
}

Try / catch

try { normalizeGuidedInstallRequest(input); }
catch (error) {
  if (/at least one guided harness/i.test(error.message)) {
    console.error('Pass harnesses: [\'claude\'], [\'codex\'], [\'kimi\'], or a combination.');
    return;
  }
  throw error;
}

Prevention

When it happens

Trigger: Calling normalizeGuidedInstallRequest (or the guided install CLI that wraps it) with no harnesses argument, an empty array, or an array of values none of which normalize to 'claude', 'codex', or 'kimi'.

Common situations: CLI invocation without a --harness flag; passing harnesses under the wrong key (e.g. harness instead of harnesses); typos like 'claudecode' or 'Kimi' with case-sensitivity issues in a custom wrapper; a UI defaulting to an empty selection.

Related errors


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