can1357/oh-my-pi · error · Error
Plugin "${id}" not found in registry
Error message
Plugin "${id}" not found in registry What it means
removeInstalledPlugin() deletes the plugin's entry list from the InstalledPluginsRegistry keyed by full plugin id ("name@marketplace"). If the id is not a key in reg.plugins, it throws rather than returning the registry unchanged, so callers know the uninstall targeted nothing.
Source
Thrown at packages/coding-agent/src/extensibility/plugins/marketplace/registry.ts:169
}
// ── Installed plugin CRUD ────────────────────────────────────────────
export function addInstalledPlugin(
reg: InstalledPluginsRegistry,
id: string,
entry: InstalledPluginEntry,
): InstalledPluginsRegistry {
const existing = reg.plugins[id] ?? [];
return {
...reg,
plugins: { ...reg.plugins, [id]: [...existing, entry] },
};
}
export function removeInstalledPlugin(reg: InstalledPluginsRegistry, id: string): InstalledPluginsRegistry {
if (!(id in reg.plugins)) {
throw new Error(`Plugin "${id}" not found in registry`);
}
const { [id]: _, ...rest } = reg.plugins;
return { ...reg, plugins: rest };
}
export function getInstalledPlugin(reg: InstalledPluginsRegistry, id: string): InstalledPluginEntry[] | undefined {
return reg.plugins[id];
}
/**
* Collect all installPath values referenced by any of the provided registries.
* Use this before deleting a cached plugin directory to verify it is not still
* referenced by another scope's registry.
*/
export function collectReferencedPaths(...registries: InstalledPluginsRegistry[]): Set<string> {
return new Set(
registries.flatMap(r =>
Object.values(r.plugins)View on GitHub (pinned to 9690622007)
Solutions
- Confirm the exact key with getInstalledPlugin(reg, id) before removing
- Use the fully qualified id "name@marketplace" matching the registry key
- Make uninstall idempotent: check `id in reg.plugins` first and skip when absent
- Reinstall if it was already removed and uninstall is genuinely needed again
Example fix
// before
reg = removeInstalledPlugin(reg, "myplugin"); // throws — key is "myplugin@community"
// after
if (getInstalledPlugin(reg, "myplugin@community")) {
reg = removeInstalledPlugin(reg, "myplugin@community");
} Defensive patterns
Strategy: validation
Validate before calling
import { getInstalledPlugin, removeInstalledPlugin } from './registry';
const id = `${name}@${marketplace}`;
if (getInstalledPlugin(reg, id)) {
reg = removeInstalledPlugin(reg, id);
} Type guard
null
Try / catch
try {
reg = removeInstalledPlugin(reg, id);
} catch (err) {
if (err.message === `Plugin "${id}" not found in registry`) {
// already uninstalled — idempotent no-op
} else throw err;
} Prevention
- Key uninstall operations on the full "name@marketplace" id as stored in reg.plugins
- Check getInstalledPlugin before removing to keep scripts idempotent
- Load the correct registry (user vs project) for the scope you intend
- Avoid hand-building ids — reuse values read from the registry
When it happens
Trigger: Calling removeInstalledPlugin(reg, id) for a plugin never installed, already uninstalled, or under an id that differs from the stored key (missing @marketplace suffix, different marketplace name, case mismatch).
Common situations: Double-uninstall from retrying a failed script; uninstalling in a project where only the user-scope registry has the plugin (or vice versa); constructing the id by hand without the @marketplace part while the registry keys are fully qualified.
Related errors
- Marketplace "${name}" not found
- Marketplace "${name}" not found
- Marketplace "${marketplace}" not found
- Marketplace "${entry.name}" already exists
- Plugin ${name} not found in runtime config
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/e743fdf6afe0b9f1.
Report an issue: GitHub.