{"record":{"id":"4b384fe2ab5ac2e4","repo":"can1357/oh-my-pi","slug":"plugin-pluginid-is-not-installed-in-project-s","errorCode":null,"errorMessage":"Plugin \"${pluginId}\" is not installed in project scope","messagePattern":"Plugin \"(.+?)\" is not installed in project scope","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/extensibility/plugins/marketplace/manager.ts","lineNumber":476,"sourceCode":"\t\t}\n\n\t\t// Disambiguation: if installed in both scopes and no explicit scope, require one.\n\t\tlet targetScope: \"user\" | \"project\";\n\t\tif (inUser && inProject) {\n\t\t\tif (!scope) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Plugin \"${pluginId}\" is installed in both user and project scope. Use --scope user or --scope project to specify which to remove.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\ttargetScope = scope;\n\t\t} else if (inProject) {\n\t\t\tif (scope === \"user\") {\n\t\t\t\tthrow new Error(`Plugin \"${pluginId}\" is not installed in user scope`);\n\t\t\t}\n\t\t\ttargetScope = \"project\";\n\t\t} else {\n\t\t\tif (scope === \"project\") {\n\t\t\t\tthrow new Error(`Plugin \"${pluginId}\" is not installed in project scope`);\n\t\t\t}\n\t\t\ttargetScope = \"user\";\n\t\t}\n\n\t\tconst targetEntries = targetScope === \"project\" ? projectEntries! : userEntries!;\n\t\tconst targetReg = targetScope === \"project\" ? projectReg : userReg;\n\t\tconst registryPath = this.#registryPath(targetScope);\n\t\tconst packageNames = await this.#resolveInstalledPackageNames(targetEntries, parsed.name);\n\n\t\tif (options?.dryRun) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst updatedReg = removeInstalledPlugin(targetReg, pluginId);\n\t\tawait writeInstalledPluginsRegistry(registryPath, updatedReg);\n\n\t\t// Read both registries AFTER removal — only delete paths no longer referenced by either.\n\t\tconst [freshUserReg, freshProjectReg] = await Promise.all([","sourceCodeStart":458,"sourceCodeEnd":494,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/extensibility/plugins/marketplace/manager.ts#L458-L494","documentation":"MarketplaceManager.uninstallPlugin() resolves which registry (user-level or project-level) holds the plugin before removing it. This error is thrown when the caller explicitly passed scope=\"project\", but the plugin id was only found in the user-scope installed-plugins registry, so uninstalling from project scope is impossible. It prevents silently modifying the wrong registry or removing a plugin that is not actually installed where the user asked.","triggerScenarios":"Calling `uninstallPlugin(pluginId, \"project\")` (or the equivalent `omp plugin uninstall <id> --scope project` CLI path) when `#findInBothRegistries(pluginId)` returns projectEntries empty/undefined but userEntries non-empty.","commonSituations":"The plugin was installed with `plugin install --scope user` (the default for personal setups) but the uninstall command repeats `--scope project` copied from a teammate or CI script; the project-local registry file (e.g. .omp/plugins in the repo) was deleted or the command is run outside the project directory, so only the user registry still lists the plugin.","solutions":["Re-run without the --scope flag so the manager auto-targets the scope where the plugin is actually installed.","Re-run with `--scope user` to uninstall from the user registry where the plugin is actually recorded.","Verify where the plugin is installed with `omp plugin list` (it shows per-scope entries) before specifying a scope."],"exampleFix":"// before\nawait manager.uninstallPlugin(\"formatter@team\", \"project\");\n// after\nawait manager.uninstallPlugin(\"formatter@team\", \"user\"); // or omit scope to auto-resolve","handlingStrategy":"validation","validationCode":"import { MarketplaceManager } from \"./manager\";\nconst installed = await manager.listInstalledPlugins();\nconst entry = installed.find(p => p.id === pluginId);\nif (!entry) throw new Error(`Plugin ${pluginId} is not installed`);\nif (scope === \"project\" && entry.scope !== \"project\") {\n  scope = entry.scope; // retarget to the scope where it actually lives\n}","typeGuard":"function isInScope(entry: { id: string; scope: \"user\" | \"project\" } | undefined, scope: \"user\" | \"project\"): entry is { id: string; scope: \"user\" | \"project\" } {\n  return entry !== undefined && entry.scope === scope;\n}","tryCatchPattern":"try {\n  await manager.uninstallPlugin(pluginId, \"project\");\n} catch (err) {\n  if (err instanceof Error && err.message.includes('is not installed in project scope')) {\n    await manager.uninstallPlugin(pluginId); // let the manager resolve the scope\n  } else throw err;\n}","preventionTips":["Call listInstalledPlugins() and inspect the returned scope before passing an explicit scope.","Omit the scope argument whenever only one installation exists; pass it only after a both-scopes conflict.","Keep CLI scripts free of hardcoded --scope values copied from other machines."],"tags":["plugins","marketplace","scope-mismatch","configuration"],"backgroundTag":"plugin-not-installed-in-scope","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}