can1357/oh-my-pi · error · Error
Marketplace "${entry.name}" already exists
Error message
Marketplace "${entry.name}" already exists What it means
addMarketplaceEntry() is a pure registry transform that enforces unique marketplace names. If the registry already contains a marketplace with the same name, it throws instead of silently overwriting the existing entry (which would lose the old source/catalogPath). Callers are expected to remove or update the entry explicitly.
Source
Thrown at packages/coding-agent/src/extensibility/plugins/marketplace/registry.ts:136
// Accept any numeric version — forward compatible reads
return { ...data, version: 2 };
} catch (err) {
if (isEnoent(err)) return emptyInstalledPluginsRegistry();
throw err;
}
}
export async function writeInstalledPluginsRegistry(filePath: string, reg: InstalledPluginsRegistry): Promise<void> {
await atomicWriteJson(filePath, reg);
}
// ── Marketplace CRUD ─────────────────────────────────────────────────
// Pure functions that transform registry state. Caller is responsible for
// reading, mutating, and writing back.
export function addMarketplaceEntry(reg: MarketplacesRegistry, entry: MarketplaceRegistryEntry): MarketplacesRegistry {
if (reg.marketplaces.some(m => m.name === entry.name)) {
throw new Error(`Marketplace "${entry.name}" already exists`);
}
return { ...reg, marketplaces: [...reg.marketplaces, entry] };
}
export function removeMarketplaceEntry(reg: MarketplacesRegistry, name: string): MarketplacesRegistry {
const filtered = reg.marketplaces.filter(m => m.name !== name);
if (filtered.length === reg.marketplaces.length) {
throw new Error(`Marketplace "${name}" not found`);
}
return { ...reg, marketplaces: filtered };
}
export function getMarketplaceEntry(reg: MarketplacesRegistry, name: string): MarketplaceRegistryEntry | undefined {
return reg.marketplaces.find(m => m.name === name);
}
// ── Installed plugin CRUD ────────────────────────────────────────────
View on GitHub (pinned to 9690622007)
Solutions
- Check existence first with getMarketplaceEntry() and skip or replace the entry
- Remove the existing marketplace (removeMarketplaceEntry) then re-add with the desired source
- Use an update flow that mutates the existing entry in place instead of appending
- Choose a different marketplace name if both sources are wanted
Example fix
// before
reg = addMarketplaceEntry(reg, entry); // throws if exists
// after
if (!getMarketplaceEntry(reg, entry.name)) {
reg = addMarketplaceEntry(reg, entry);
} else {
reg = removeMarketplaceEntry(reg, entry.name);
reg = addMarketplaceEntry(reg, entry);
} Defensive patterns
Strategy: validation
Validate before calling
import { getMarketplaceEntry, addMarketplaceEntry, removeMarketplaceEntry } from './registry';
if (getMarketplaceEntry(reg, entry.name)) {
reg = removeMarketplaceEntry(reg, entry.name);
}
reg = addMarketplaceEntry(reg, entry); Type guard
null
Try / catch
try {
reg = addMarketplaceEntry(reg, entry);
} catch (err) {
if (err.message === `Marketplace "${entry.name}" already exists`) {
reg = removeMarketplaceEntry(reg, entry.name);
reg = addMarketplaceEntry(reg, entry); // replace
} else throw err;
} Prevention
- Make add-marketplace scripts idempotent with an existence check
- Pick unique marketplace names when registering multiple sources
- Use the update flow for existing marketplaces instead of add
- Check getMarketplaceEntry before re-running setup scripts
When it happens
Trigger: Calling addMarketplaceEntry() with a name already present in reg.marketplaces — e.g. re-running a "marketplace add" for an existing marketplace, or an update flow that adds instead of replacing.
Common situations: Re-running a setup script that adds marketplaces idempotently but does not check existence; adding a marketplace whose name collides with a previously registered one from a different source; a partially-failed update that left the entry in place.
Related errors
- Marketplace "${catalog.name}" already exists
- Marketplace "${name}" not found
- Plugin "${id}" not found in registry
- Marketplace "${name}" not found
- Marketplace catalog name changed from "${name}" to "${catalo
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/21b4c635af4ccb00.
Report an issue: GitHub.