can1357/oh-my-pi · error · Error

Failed to uninstall ${name}

Error message

Failed to uninstall ${name}

What it means

uninstallPlugin spawns `bun remove <name>` in the plugins directory and captures stdout/stderr. If the child exits non-zero it throws this bare error. Notably the captured stderr is discarded, so the message omits the underlying bun failure reason.

Source

Thrown at packages/coding-agent/src/extensibility/plugins/installer.ts:109

	validatePackageName(name);

	await ensurePluginsDir();

	const proc = Bun.spawn(["bun", "uninstall", name], {
		cwd: PLUGINS_DIR,
		stdin: "ignore",
		stdout: "pipe",
		stderr: "pipe",
		windowsHide: true,
	});

	const [exitCode] = await Promise.all([
		proc.exited,
		new Response(proc.stdout).text(),
		new Response(proc.stderr).text(),
	]);
	if (exitCode !== 0) {
		throw new Error(`Failed to uninstall ${name}`);
	}
}

export async function listPlugins(): Promise<InstalledPlugin[]> {
	const pkgJsonPath = Bun.file(path.join(PLUGINS_DIR, "package.json"));
	if (!(await pkgJsonPath.exists())) {
		return [];
	}

	const pkg = await pkgJsonPath.json();
	const deps = pkg.dependencies || {};

	const plugins: InstalledPlugin[] = [];
	for (const [name, _version] of Object.entries(deps)) {
		const pluginPath = path.join(PLUGINS_DIR, "node_modules", name);
		const fpkg = Bun.file(path.join(pluginPath, "package.json"));
		if (await fpkg.exists()) {
			const pkg = await fpkg.json();

View on GitHub (pinned to 9690622007)

Solutions

  1. Confirm the plugin is actually installed (`omp plugins list` or inspect ~/.omp/plugins/package.json dependencies)
  2. Run `bun remove <name>` manually inside ~/.omp/plugins to see the real bun error
  3. Delete the entry from ~/.omp/plugins/package.json and remove node_modules/<name> manually if the lockfile is inconsistent
  4. Ensure the plugins directory is writable and not locked by another running instance

Example fix

// before
await uninstallPlugin("not-installed-plugin");
// after: check installed set first
const installed = await listPlugins();
if (installed.some(p => p.name === "not-installed-plugin")) {
	await uninstallPlugin("not-installed-plugin");
}
Defensive patterns

Strategy: try-catch

Validate before calling

const plugins = await listPlugins();
if (!plugins.some(p => p.name === targetName)) return; // nothing to uninstall
const pkgJson = await Bun.file(path.join(agentDir, "plugins", "package.json")).json();
if (!pkgJson.dependencies?.[targetName]) return;

Try / catch

try {
	await uninstallPlugin(name);
} catch (err) {
	// Error message lacks bun stderr; inspect ~/.omp/plugins directly
	if (err instanceof Error && err.message.startsWith("Failed to uninstall")) {
		// fall back to manual cleanup: edit plugins/package.json + rm node_modules/<name>
	}
	throw err;
}

Prevention

When it happens

Trigger: uninstallPlugin(name) is called while `bun remove` fails: the package is not present in PLUGINS_DIR/package.json dependencies or node_modules, the plugins package.json is corrupted, or another process holds a lock on the bun install directory.

Common situations: Trying to uninstall a plugin that was already removed or never installed via this mechanism; plugins installed by a different version of the CLI with a different layout; read-only or locked ~/.omp/plugins directory.

Related errors


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