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

  1. Confirm the exact key with getInstalledPlugin(reg, id) before removing
  2. Use the fully qualified id "name@marketplace" matching the registry key
  3. Make uninstall idempotent: check `id in reg.plugins` first and skip when absent
  4. 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

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/e743fdf6afe0b9f1. Report an issue: GitHub.