affaan-m/ECC · error

INVALID_SCOPE

INVALID_SCOPE

Error message

Scope migration requires --scope user, project, or local.

What it means

ClaudeSetupError with code INVALID_SCOPE thrown at the entry of migrateClaudePluginScope in scripts/lib/claude-scope-migration.js:248. The destination scope is validated against the VALID_SCOPES set ('user', 'project', 'local') before any migration work begins. Any other value — misspelled scopes, empty values, or unsupported targets like 'global' — is rejected immediately with this message so invalid input never reaches Claude CLI calls.

Solutions

  1. Use one of the three supported values: `--scope user`, `--scope project`, or `--scope local`.
  2. If the value comes from a variable, echo it first to confirm it is non-empty and correctly spelled.
  3. Check case — the validation is exact-match against lowercase scope names.
  4. If calling the JS API directly, pass `{ scope: 'project' }` (etc.) in options rather than a nested or renamed key.

Example fix

// before
// ecc migrate-scope --scope global

// after
// ecc migrate-scope --scope user
Defensive patterns

Strategy: validation

Validate before calling

const VALID_SCOPES = new Set(['user', 'project', 'local']);
if (!VALID_SCOPES.has(scope)) {
  throw new Error(`Scope migration requires --scope user, project, or local (got: ${scope})`);
}

Type guard

function isValidScope(v) { return typeof v === 'string' && ['user', 'project', 'local'].includes(v); }

Try / catch

try { await migrateClaudePluginScope({ scope }) }
catch (e) {
  if (e.code === 'INVALID_SCOPE') { console.error(e.message); process.exitCode = 2; }
  else throw e;
}

Prevention

When it happens

Trigger: Invoking the scope migration API or CLI with `options.scope` set to anything other than exactly 'user', 'project', or 'local' — e.g. `--scope global`, `--scope User` (case-sensitive), `--scope ''`, or omitting the scope entirely (undefined fails the Set check).

Common situations: Typo in a CLI flag value; assuming a 'global' or 'workspace' scope exists; shell variable expansion producing an empty --scope value; case-sensitivity mistakes ('User' vs 'user').

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at scripts/lib/claude-scope-migration.js:248

      }
    );
  }
}

function verifyFinalState(run, paths, destinationScope) {
  const plugins = readPluginInventory(run, paths.projectRoot, 'final-verification');
  return validateExpectedScopes(plugins, [destinationScope], {
    code: 'FINAL_VERIFICATION_FAILED',
    destinationScope,
    message: `Could not verify destination-only ${CURRENT_PLUGIN_ID} state after source cleanup.`,
    phase: 'final-verification',
    recovery: recoveryCommands(null, destinationScope),
  });
}

function migrateClaudePluginScope(options = {}, dependencies = {}) {
  if (!VALID_SCOPES.has(options.scope)) {
    throw migrationError(
      'INVALID_SCOPE',
      'Scope migration requires --scope user, project, or local.'
    );
  }
  if (options.hooks !== undefined && !VALID_HOOK_MODES.has(options.hooks)) {
    throw migrationError('INVALID_HOOK_MODE', `Invalid hook mode: ${options.hooks}`);
  }

  const paths = resolveClaudePaths(options);
  const settingsPath = path.join(paths.configDir, 'settings.json');
  const settings = readSettings(settingsPath);
  assertSafeLocalInventory(paths);
  assertGitAvailable(
    { cwd: paths.projectRoot },
    { spawnSync: dependencies.spawnSync }
  );
  const providerRun = dependencies.runClaude || runClaude;
  const run = options.dryRun

View on GitHub (pinned to 8321021c54)