can1357/oh-my-pi · error · Error
Plugin "${pluginId}" is installed in both user and project s
Error message
Plugin "${pluginId}" is installed in both user and project scope. Use --scope user or --scope project to specify which to modify. What it means
When a plugin id exists in BOTH the user-scope and project-scope installed-plugins registries, setPluginEnabled() refuses to guess which copy the caller means and throws this error, asking for an explicit scope. This avoids toggling enablement on the wrong installation — the project copy normally shadows the user copy, and the two have independent enabled flags.
Source
Thrown at packages/coding-agent/src/extensibility/plugins/marketplace/manager.ts:568
}
return results;
}
async setPluginEnabled(pluginId: string, enabled: boolean, scope?: "user" | "project"): Promise<void> {
const { userEntries, projectEntries, userReg, projectReg } = await this.#findInBothRegistries(pluginId);
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 modify.`,
);
}
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 reg = targetScope === "project" ? projectReg : userReg;
const entries = targetScope === "project" ? projectEntries! : userEntries!;View on GitHub (pinned to 9690622007)
Solutions
- Pass an explicit scope: `--scope project` to modify the project-local copy (usually what shadows at runtime), or `--scope user` for the global one.
- In code, call setPluginEnabled(id, enabled, "project") or (id, enabled, "user") instead of omitting the third argument.
- If only one copy is needed, uninstall the redundant scope first so future scope-less calls resolve unambiguously.
Example fix
// before
await manager.setPluginEnabled("formatter@team", false);
// after
await manager.setPluginEnabled("formatter@team", false, "project"); Defensive patterns
Strategy: validation
Validate before calling
const installed = await manager.listInstalledPlugins();
const copies = installed.filter(p => p.id === pluginId);
if (copies.length > 1 && !scope) {
scope = "project"; // project copy shadows user copy; pick explicitly
} Type guard
function needsExplicitScope(copies: { scope: "user" | "project" }[]): boolean {
return copies.some(c => c.scope === "user") && copies.some(c => c.scope === "project");
} Try / catch
try {
await manager.setPluginEnabled(pluginId, enabled);
} catch (err) {
if (err instanceof Error && err.message.includes("installed in both user and project scope")) {
await manager.setPluginEnabled(pluginId, enabled, "project");
} else throw err;
} Prevention
- Always pass an explicit scope in scripts; reserve scope-less calls for interactive use.
- Prefer "project" when both copies exist, since the enabled project copy shadows the user one.
- Avoid installing the same plugin at both scopes; uninstall the redundant copy.
When it happens
Trigger: Calling `setPluginEnabled(pluginId, enabled)` with the `scope` argument omitted (or the CLI omitting --scope) while `#findInBothRegistries(pluginId)` returns non-empty entries for both userEntries and projectEntries.
Common situations: A plugin was originally installed at user scope and later also installed into a project (or vice versa); a team repo committed a project-scope plugin registry for something the developer already had globally; scripted automation that never passes --scope starts failing after a second-scope install.
Related errors
- Plugin "${pluginId}" is not installed in project scope
- Plugin ${name} not found in runtime config
- Unknown feature "${feat}" in ${name}. Available: ${Object.ke
- Invalid marketplace name for cache: "${marketplace}"
- Invalid plugin name for cache: "${pluginName}"
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/63691c13f5010ce5.
Report an issue: GitHub.