affaan-m/ECC · error
MARKETPLACE_COLLISION
MARKETPLACE_COLLISION
Error message
Refusing the `ecc` marketplace collision because it is not the official affaan-m/ECC source.
What it means
ClaudeSetupError with code MARKETPLACE_COLLISION thrown by migrateClaudePluginScope in scripts/lib/claude-scope-migration.js:287 during the 'marketplace-inventory' phase. The migration inspects `claude plugin marketplace list --json` for a marketplace named 'ecc'. If one exists but isOfficialMarketplace() determines it does not point at the official affaan-m/ECC source (OFFICIAL_MARKETPLACE_URL), the tool refuses to proceed: installing/ensuring the official marketplace could clobber or conflict with a third-party marketplace that squats the 'ecc' name.
Solutions
- Inspect the conflicting entry: `claude plugin marketplace list --json` and compare its source against the official affaan-m/ECC URL.
- Remove the non-official marketplace: `claude plugin marketplace remove ecc`, then re-run the migration (it will re-add the official marketplace).
- If the marketplace is intentional (internal mirror), unregister it under that name and register the official source, or migrate manually without the automated tool.
- If the URL is merely outdated (repo moved), update the marketplace registration to the official URL and retry.
Example fix
// before: a fork registered as 'ecc' // claude plugin marketplace remove ecc // after: official source re-registered by the migration // ecc migrate-scope --scope project
Defensive patterns
Strategy: validation
Validate before calling
const marketplaces = JSON.parse(run(['plugin', 'marketplace', 'list', '--json'], { cwd }).stdout);
const named = marketplaces.find(m => m?.name === 'ecc');
if (named && !isOfficialMarketplace(named)) {
console.error("Non-official marketplace named 'ecc' found; remove it: claude plugin marketplace remove ecc");
process.exit(1);
} Type guard
function isOfficialEccMarketplace(entry, officialUrl) { return !!entry && entry.name === 'ecc' && (entry.source === officialUrl || entry.url === officialUrl); } Try / catch
try { await migrateClaudePluginScope({ scope }) }
catch (e) {
if (e.code === 'MARKETPLACE_COLLISION') {
console.log('Resolve the collision, then retry:', e.details.phase);
} else throw e;
} Prevention
- Register forks or mirrors under a different marketplace name than 'ecc'.
- Audit `claude plugin marketplace list --json` for name squatters before setup.
- Keep the official marketplace registration pointing at affaan-m/ECC.
- Update stale marketplace URLs after upstream repo moves.
When it happens
Trigger: Running a scope migration when the local Claude config contains a marketplace registered under the name 'ecc' whose source URL/repo differs from the official affaan-m/ECC marketplace — e.g. a fork, a mirror, or a maliciously/accidentally registered same-named marketplace.
Common situations: Previously added a community fork of ECC as a marketplace named 'ecc'; a company-internal mirror registered under the same name; an old marketplace registration pointing at a moved or renamed repo so the URL no longer matches the official one.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- AMBIGUOUS_PLUGIN_SCOPES
- artifact must be a resident regular file
- artifact path escapes output directory
- artifact path must be canonical and absolute
- artifact permits provider execution
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/acac7df7e190008b.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/claude-scope-migration.js:287
const plugins = readPluginInventory(run, paths.projectRoot, 'inventory');
const migration = assertMigrationInventory(plugins, options.scope);
const hooks = options.hooks === undefined
? deriveHookMode(settings)
: options.hooks;
const hookConfiguration = options.hooks === undefined
? readStoredHookOptions(settings)
: hookOptions(options.hooks);
const needsCommitAttributionPreference = needsClaudeCommitAttributionPreferenceWrite(settings);
const marketplaces = parseMarketplaceList(
run(
['plugin', 'marketplace', 'list', '--json'],
{ cwd: paths.projectRoot, phase: 'marketplace-inventory' }
).stdout
);
const namedMarketplace = marketplaces.find(entry => entry?.name === 'ecc');
if (namedMarketplace && !isOfficialMarketplace(namedMarketplace)) {
throw migrationError(
'MARKETPLACE_COLLISION',
'Refusing the `ecc` marketplace collision because it is not the official affaan-m/ECC source.',
{
phase: 'marketplace-inventory',
observedScopes: migration.observedScopes,
}
);
}
if (migration.mode === 'already-migrated') {
const result = {
action: 'already-migrated',
hooks,
pluginId: CURRENT_PLUGIN_ID,
sourceScope: null,
scope: options.scope,
};
if (options.dryRun) {View on GitHub (pinned to 8321021c54)