affaan-m/ECC · error · Error

Invalid Claude scope: ${claudeScope}

Error message

Invalid Claude scope: ${claudeScope}

What it means

When Claude is selected, claudeScope must be one of the allowed scopes — user, project, or local (the VALID_CLAUDE_SCOPES set). These map to where the Claude plugin config is written (~/.claude, <project>/.claude, or a local overlay). Any other value is rejected because it would direct writes to an unmanaged location. The check only fires when Claude is selected (otherwise claudeScope is undefined).

Source

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

  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)) {
    throw new Error(`Invalid Claude hooks preference: ${claudeHooks}`);
  }
  if (profile && !VALID_PROFILES.has(profile)) {
    throw new Error(`Invalid Kimi install profile: ${profile}`);
  }

  return {
    harnesses,
    ...(claudeHooks ? { claudeHooks } : {}),
    ...(claudeScope ? { claudeScope } : {}),
    dryRun: Boolean(input.dryRun),
    json: Boolean(input.json),
    ...(profile ? { profile } : {}),
    yes: Boolean(input.yes),
  };
}

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Use one of the three valid scopes: 'user' (default, writes to ~/.claude), 'project' (writes to <project>/.claude), or 'local'.
  2. Omit claudeScope to accept the default ('user').
  3. If you need a custom install location, that is not supported via claudeScope — use the ECC plugin's own path overrides instead.
  4. Check for typos and trim/case issues — values are matched exactly against the lowercase set.

Example fix

// before
normalizeGuidedInstallRequest({ harnesses: ['claude'], claudeScope: 'global' }); // throws
// after
normalizeGuidedInstallRequest({ harnesses: ['claude'], claudeScope: 'project' });
// or omit for the default
normalizeGuidedInstallRequest({ harnesses: ['claude'] });
Defensive patterns

Strategy: validation

Validate before calling

const { VALID_CLAUDE_SCOPES } = require('./scripts/lib/multi-harness-setup');
function assertClaudeScope(value) {
  if (value !== undefined && !VALID_CLAUDE_SCOPES.has(value)) {
    throw new Error(`Invalid Claude scope: ${value}`);
  }
  return value;
}

Type guard

function isValidClaudeScope(v) {
  return v === undefined || new Set(['user','project','local']).has(v);
}

Try / catch

try { normalizeGuidedInstallRequest(input); }
catch (error) {
  if (/Invalid Claude scope/i.test(error.message)) {
    console.error('claudeScope must be one of: user, project, local.');
    return;
  }
  throw error;
}

Prevention

When it happens

Trigger: Calling normalizeGuidedInstallRequest with harnesses including 'claude' and a claudeScope outside {user, project, local}. Examples: 'global', 'system', 'repo', an empty string, or a typo like 'usr'.

Common situations: Typing the scope name; assuming 'global' is valid because other tools use it; passing a path instead of the scope keyword; stale config from an older API that accepted different scope names; a UI dropdown with the wrong value list.

Related errors


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