can1357/oh-my-pi · error · Error

Plugin " " 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.

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.

Appendix: 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)