affaan-m/ECC · error
PLUGIN_NOT_INSTALLED
PLUGIN_NOT_INSTALLED
Error message
${CURRENT_PLUGIN_ID} is not installed, so there is no source scope to migrate. What it means
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.
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.
Example fix
// before: migrate with nothing installed // ecc migrate-scope --scope project // after: install first, then migrate if needed // ecc setup --mode claude-plugin --scope project --yes
Defensive patterns
Strategy: validation
Validate before calling
const list = JSON.parse(run(['plugin', 'list', '--json'], { cwd }).stdout);
const installed = list.filter(p => p.id === CURRENT_PLUGIN_ID);
if (installed.length === 0) {
console.error('ECC plugin not installed; run: ecc setup --mode claude-plugin --scope <scope> --yes');
process.exit(1);
} Type guard
function isInstalled(plugins, pluginId) { return Array.isArray(plugins) && plugins.some(p => p && p.id === pluginId); } Try / catch
try { await migrateScope({ scope }) }
catch (e) {
if (e.code === 'PLUGIN_NOT_INSTALLED') {
console.log('Run the recovery command:', e.details.recovery[0]);
} else throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- AMBIGUOUS_PLUGIN_SCOPES
- SOURCE_UNINSTALL_FAILED
- DESTINATION_VERIFICATION_FAILED
- INVALID_SCOPE
- Agents directory not found
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/b6dc156f0936063d.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/claude-scope-migration.js:64
}
function readPluginInventory(run, projectRoot, phase) {
return parsePluginList(
run(
['plugin', 'list', '--json'],
{ cwd: projectRoot, phase }
).stdout
);
}
function assertMigrationInventory(plugins, destinationScope) {
assertNoConflictingEccPlugins(plugins);
const installed = currentEccPlugins(plugins);
const observedScopes = installed.map(plugin => plugin.scope);
const uniqueScopes = new Set(observedScopes);
if (installed.length === 0) {
throw migrationError(
'PLUGIN_NOT_INSTALLED',
`${CURRENT_PLUGIN_ID} is not installed, so there is no source scope to migrate.`,
{
observedScopes,
recovery: [
`ecc setup --mode claude-plugin --scope ${destinationScope} --yes`,
],
}
);
}
if (
installed.length > 2
|| uniqueScopes.size !== installed.length
|| (
installed.length === 2
&& !uniqueScopes.has(destinationScope)
)
) {View on GitHub (pinned to 8321021c54)