{"record":{"id":"b7667c816d3ab517","repo":"can1357/oh-my-pi","slug":"failed-to-uninstall-name","errorCode":null,"errorMessage":"Failed to uninstall ${name}","messagePattern":"Failed to uninstall (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/extensibility/plugins/installer.ts","lineNumber":109,"sourceCode":"\tvalidatePackageName(name);\n\n\tawait ensurePluginsDir();\n\n\tconst proc = Bun.spawn([\"bun\", \"uninstall\", name], {\n\t\tcwd: PLUGINS_DIR,\n\t\tstdin: \"ignore\",\n\t\tstdout: \"pipe\",\n\t\tstderr: \"pipe\",\n\t\twindowsHide: true,\n\t});\n\n\tconst [exitCode] = await Promise.all([\n\t\tproc.exited,\n\t\tnew Response(proc.stdout).text(),\n\t\tnew Response(proc.stderr).text(),\n\t]);\n\tif (exitCode !== 0) {\n\t\tthrow new Error(`Failed to uninstall ${name}`);\n\t}\n}\n\nexport async function listPlugins(): Promise<InstalledPlugin[]> {\n\tconst pkgJsonPath = Bun.file(path.join(PLUGINS_DIR, \"package.json\"));\n\tif (!(await pkgJsonPath.exists())) {\n\t\treturn [];\n\t}\n\n\tconst pkg = await pkgJsonPath.json();\n\tconst deps = pkg.dependencies || {};\n\n\tconst plugins: InstalledPlugin[] = [];\n\tfor (const [name, _version] of Object.entries(deps)) {\n\t\tconst pluginPath = path.join(PLUGINS_DIR, \"node_modules\", name);\n\t\tconst fpkg = Bun.file(path.join(pluginPath, \"package.json\"));\n\t\tif (await fpkg.exists()) {\n\t\t\tconst pkg = await fpkg.json();","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/extensibility/plugins/installer.ts#L91-L127","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Confirm the plugin is actually installed (`omp plugins list` or inspect ~/.omp/plugins/package.json dependencies)","Run `bun remove <name>` manually inside ~/.omp/plugins to see the real bun error","Delete the entry from ~/.omp/plugins/package.json and remove node_modules/<name> manually if the lockfile is inconsistent","Ensure the plugins directory is writable and not locked by another running instance"],"exampleFix":"// before\nawait uninstallPlugin(\"not-installed-plugin\");\n// after: check installed set first\nconst installed = await listPlugins();\nif (installed.some(p => p.name === \"not-installed-plugin\")) {\n\tawait uninstallPlugin(\"not-installed-plugin\");\n}","handlingStrategy":"try-catch","validationCode":"const plugins = await listPlugins();\nif (!plugins.some(p => p.name === targetName)) return; // nothing to uninstall\nconst pkgJson = await Bun.file(path.join(agentDir, \"plugins\", \"package.json\")).json();\nif (!pkgJson.dependencies?.[targetName]) return;","typeGuard":null,"tryCatchPattern":"try {\n\tawait uninstallPlugin(name);\n} catch (err) {\n\t// Error message lacks bun stderr; inspect ~/.omp/plugins directly\n\tif (err instanceof Error && err.message.startsWith(\"Failed to uninstall\")) {\n\t\t// fall back to manual cleanup: edit plugins/package.json + rm node_modules/<name>\n\t}\n\tthrow err;\n}","preventionTips":["Check listPlugins() before uninstalling to avoid removing non-existent packages","Avoid running two CLI instances that touch ~/.omp/plugins concurrently","Keep ~/.omp/plugins writable and out of synced/locked folders"],"tags":["plugins","npm-uninstall","process-exit-code","package-management"],"backgroundTag":"bun-remove-nonzero-exit","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}