different-ai/openwork · error

Marketplace package is not installed in this workspace.

Error message

Marketplace package is not installed in this workspace.

What it means

removeCloudOrgPlugin removes a marketplace (cloud) plugin from the workspace. When there is no OpenWork server client, it falls back to local removal and looks the plugin up in snapshot.importedCloudPlugins; if the given pluginId is not present in that local record of imported cloud plugins, removal cannot proceed and this error is thrown.

Source

Thrown at apps/app/src/react-app/domains/settings/state/extensions-store.ts:1337

    options.setBusy(true);
    options.setError(null);
    setStateField("cloudOrgMarketplacesStatus", null);

    try {
      const target = await resolveWorkspaceServerTarget();
      if (target.openworkClient && target.openworkWorkspaceId) {
        const result = await target.openworkClient.removeCloudPlugin(target.openworkWorkspaceId, pluginId);
        await refreshSkills({ force: true });
        await refreshCloudOrgMarketplaces({ force: true });
        void refreshPendingCloudPluginChanges();
        return {
          ok: true,
          message: `Removed ${result.item.name}.`,
        };
      }

      const imported = snapshot.importedCloudPlugins[pluginId];
      if (!imported) throw new Error("Marketplace package is not installed in this workspace.");

      const removedMcpNames: string[] = [];
      const fileDeletes: Array<{ path: string; recursive?: boolean }> = [];
      for (const file of imported.files) {
        const mcpName = file.objectType === "mcp" ? cloudPluginMcpNameFromPath(file.path) : null;
        if (mcpName) {
          removedMcpNames.push(mcpName);
          continue;
        }
        if (!file.path.startsWith(".opencode/")) continue;
        const skillDir = file.path.match(/^(\.opencode\/skills\/[^/]+\/[^/]+)\/SKILL\.md$/)?.[1];
        fileDeletes.push(skillDir ? { path: skillDir, recursive: true } : { path: file.path });
      }
      await Promise.all(removedMcpNames.map((name) => deletePluginMcpConfig(name)));
      await deletePluginWorkspaceFiles(fileDeletes);

      const nextPlugins = { ...snapshot.importedCloudPlugins };
      delete nextPlugins[pluginId];

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Reconnect to the OpenWork server so removal goes through the server path (openworkClient branch), which does not need the local record.
  2. Refresh the extensions store / re-fetch imported cloud plugins so the local registry is current, then retry.
  3. Verify the pluginId against the keys of snapshot.importedCloudPlugins before calling remove.
  4. If the record is genuinely stale, clear the persisted imported-cloud-plugins state so the UI stops offering the removal.

Example fix

// before
await store.removeCloudOrgPlugin(pluginId);
// after
const installed = useExtensionsStore.getState().importedCloudPlugins[pluginId];
if (!installed) {
  toast('Plugin is no longer installed.');
  refreshCloudInventory();
  return;
}
await store.removeCloudOrgPlugin(pluginId);
Defensive patterns

Strategy: validation

Validate before calling

const installed = store.snapshot.importedCloudPlugins[pluginId];
if (!installed && !serverConnected) {
  // skip local removal; refresh inventory instead
}

Type guard

function isImportedCloudPlugin(
  registry: Record<string, unknown>, pluginId: string,
): boolean {
  return Object.prototype.hasOwnProperty.call(registry, pluginId) && !!registry[pluginId];
}

Try / catch

try {
  await store.removeCloudOrgPlugin(pluginId);
} catch (e) {
  if (e instanceof Error && e.message.includes('not installed in this workspace')) {
    await refreshCloudInventory(); // heal stale state
  } else throw e;
}

Prevention

When it happens

Trigger: Calling removeCloudOrgPlugin(pluginId) when (a) resolveWorkspaceServerTarget() has no openworkClient/openworkWorkspaceId (local fallback path) AND (b) snapshot.importedCloudPlugins[pluginId] is undefined — the id is stale, misspelled, or the plugin was imported on another workspace/server.

Common situations: Removing a plugin after switching workspaces (import record lives in the old workspace); a stale UI list showing an already-removed plugin; the plugin was imported via a server that is now disconnected so the local registry never recorded it.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/1d3b35e6f7066e3a. Report an issue: GitHub.