{"record":{"id":"b6dc156f0936063d","repo":"affaan-m/ECC","slug":"plugin-not-installed","errorCode":"PLUGIN_NOT_INSTALLED","errorMessage":"${CURRENT_PLUGIN_ID} is not installed, so there is no source scope to migrate.","messagePattern":"(.+?) is not installed, so there is no source scope to migrate\\.","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/claude-scope-migration.js","lineNumber":64,"sourceCode":"}\n\nfunction readPluginInventory(run, projectRoot, phase) {\n  return parsePluginList(\n    run(\n      ['plugin', 'list', '--json'],\n      { cwd: projectRoot, phase }\n    ).stdout\n  );\n}\n\nfunction assertMigrationInventory(plugins, destinationScope) {\n  assertNoConflictingEccPlugins(plugins);\n  const installed = currentEccPlugins(plugins);\n  const observedScopes = installed.map(plugin => plugin.scope);\n  const uniqueScopes = new Set(observedScopes);\n\n  if (installed.length === 0) {\n    throw migrationError(\n      'PLUGIN_NOT_INSTALLED',\n      `${CURRENT_PLUGIN_ID} is not installed, so there is no source scope to migrate.`,\n      {\n        observedScopes,\n        recovery: [\n          `ecc setup --mode claude-plugin --scope ${destinationScope} --yes`,\n        ],\n      }\n    );\n  }\n  if (\n    installed.length > 2\n    || uniqueScopes.size !== installed.length\n    || (\n      installed.length === 2\n      && !uniqueScopes.has(destinationScope)\n    )\n  ) {","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/claude-scope-migration.js#L46-L82","documentation":"ClaudeSetupError with code PLUGIN_NOT_INSTALLED thrown by assertMigrationInventory in scripts/lib/claude-scope-migration.js:64. Scope migration moves an installed ECC Claude plugin between scopes (user/project/local), so it requires at least one installed instance of the current plugin ID. When `claude plugin list --json` shows zero ECC plugin installations, there is no source scope to migrate from, so the command aborts and suggests running `ecc setup` to install at the destination scope instead.","triggerScenarios":"Calling migrateClaudePluginScope (via `ecc` scope-migration commands) with a --scope destination when the plugin inventory from `claude plugin list --json` contains no entries whose plugin ID matches CURRENT_PLUGIN_ID — i.e., ECC was never installed, or was fully uninstalled before the migration attempt.","commonSituations":"Running the migration on a fresh machine before ever running `ecc setup`; uninstalling the plugin manually with `claude plugin uninstall` and then trying to 'migrate' the leftover config; a typo'd or changed plugin ID in a newer ECC version making the inventory lookup miss an existing install.","solutions":["Install the plugin at the desired destination scope: `ecc setup --mode claude-plugin --scope <user|project|local> --yes` (the recovery command included in the error details).","Verify the plugin is actually visible to Claude: `claude plugin list --json` — confirm an entry matching the ECC plugin ID appears.","If you believe it is installed, check that you are running the command from the same project root / user config Claude reads; a different configDir hides the install.","If the plugin ID changed across versions, update ECC (`npm update` / git pull) so CURRENT_PLUGIN_ID matches what Claude reports."],"exampleFix":"// before: migrate with nothing installed\n// ecc migrate-scope --scope project\n\n// after: install first, then migrate if needed\n// ecc setup --mode claude-plugin --scope project --yes","handlingStrategy":"validation","validationCode":"const list = JSON.parse(run(['plugin', 'list', '--json'], { cwd }).stdout);\nconst installed = list.filter(p => p.id === CURRENT_PLUGIN_ID);\nif (installed.length === 0) {\n  console.error('ECC plugin not installed; run: ecc setup --mode claude-plugin --scope <scope> --yes');\n  process.exit(1);\n}","typeGuard":"function isInstalled(plugins, pluginId) { return Array.isArray(plugins) && plugins.some(p => p && p.id === pluginId); }","tryCatchPattern":"try { await migrateScope({ scope }) }\ncatch (e) {\n  if (e.code === 'PLUGIN_NOT_INSTALLED') {\n    console.log('Run the recovery command:', e.details.recovery[0]);\n  } else throw e;\n}","preventionTips":["Always run `ecc setup` on a machine before attempting scope migration.","Check `claude plugin list --json` for the ECC plugin ID as a pre-flight step.","Run migration commands from the same project root/config Claude uses.","Keep ECC updated so CURRENT_PLUGIN_ID matches installed plugin IDs."],"tags":["claude-plugin","scope-migration","not-installed","cli"],"backgroundTag":"entity-not-found","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}