can1357/oh-my-pi · error · Error
Plugin "${pluginId}" is not installed in user scope
Error message
Plugin "${pluginId}" is not installed in user scope What it means
During scope resolution, if the plugin is installed only in project scope but the caller explicitly requested scope "user", uninstallPlugin throws this mismatch error rather than silently uninstalling nothing or targeting the wrong scope. (The mirror error exists for scope "project" when only user-scope install exists.)
Source
Thrown at packages/coding-agent/src/extensibility/plugins/marketplace/manager.ts:471
const inUser = userEntries && userEntries.length > 0;
const inProject = projectEntries && projectEntries.length > 0;
if (!inUser && !inProject) {
throw new Error(`Plugin "${pluginId}" is not installed`);
}
// Disambiguation: if installed in both scopes and no explicit scope, require one.
let targetScope: "user" | "project";
if (inUser && inProject) {
if (!scope) {
throw new Error(
`Plugin "${pluginId}" is installed in both user and project scope. Use --scope user or --scope project to specify which to remove.`,
);
}
targetScope = scope;
} else if (inProject) {
if (scope === "user") {
throw new Error(`Plugin "${pluginId}" is not installed in user scope`);
}
targetScope = "project";
} else {
if (scope === "project") {
throw new Error(`Plugin "${pluginId}" is not installed in project scope`);
}
targetScope = "user";
}
const targetEntries = targetScope === "project" ? projectEntries! : userEntries!;
const targetReg = targetScope === "project" ? projectReg : userReg;
const registryPath = this.#registryPath(targetScope);
const packageNames = await this.#resolveInstalledPackageNames(targetEntries, parsed.name);
if (options?.dryRun) {
return;
}
View on GitHub (pinned to 9690622007)
Solutions
- Retry with the matching scope: uninstallPlugin(pluginId, "project")
- Omit the scope if only one installation exists and you want that one removed
- Confirm the installation scope via the plugin list before specifying --scope
- If you intended a user-scope install, install it at user scope first — there is nothing at user scope to remove
Example fix
// before
await manager.uninstallPlugin("formatter@community", "user");
// after
await manager.uninstallPlugin("formatter@community", "project"); // plugin is project-scoped only Defensive patterns
Strategy: validation
Validate before calling
const inUser = (await manager.listInstalledPlugins("user")).some(p => p.id === pluginId);
const inProject = (await manager.listInstalledPlugins("project")).some(p => p.id === pluginId);
if (!inUser && !inProject) return; // nothing installed
await manager.uninstallPlugin(pluginId, inUser ? "user" : "project"); Try / catch
try {
await manager.uninstallPlugin(pluginId, scope);
} catch (err) {
if (err instanceof Error && err.message.includes("is not installed in")) {
// wrong scope requested; fall back to the scope that actually has it
await manager.uninstallPlugin(pluginId, err.message.includes("user scope") ? "project" : "user");
} else throw err;
} Prevention
- Derive the scope from where the plugin actually exists instead of hardcoding it
- Check the per-scope plugin list before passing --scope
- Use one consistent scope convention across your team's setup scripts
- Treat "not installed in X scope" as a signal to inspect both registries, not to retry blindly
When it happens
Trigger: uninstallPlugin(pluginId, "user") where #findInBothRegistries found entries only in the project registry (inProject true, inUser false).
Common situations: CLI users passing --scope user out of habit when the plugin was project-installed; automation hardcoding one scope; a teammate installed the plugin at project level but you assumed it was your user-level install.
Related errors
- Plugin "${pluginId}" is not installed
- Plugin "${name}" not found in marketplace "${marketplace}"
- Plugin "${pluginId}" is already installed. Use force option
- Plugin "${name}" uses a relative source path but marketplace
- Plugin "${entry.name}" lspServers path escapes the plugin di
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/66334509e3d840cc.
Report an issue: GitHub.