{"record":{"id":"1d3b35e6f7066e3a","repo":"different-ai/openwork","slug":"marketplace-package-is-not-installed-in-this-works","errorCode":null,"errorMessage":"Marketplace package is not installed in this workspace.","messagePattern":"Marketplace package is not installed in this workspace\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/app/src/react-app/domains/settings/state/extensions-store.ts","lineNumber":1337,"sourceCode":"    options.setBusy(true);\n    options.setError(null);\n    setStateField(\"cloudOrgMarketplacesStatus\", null);\n\n    try {\n      const target = await resolveWorkspaceServerTarget();\n      if (target.openworkClient && target.openworkWorkspaceId) {\n        const result = await target.openworkClient.removeCloudPlugin(target.openworkWorkspaceId, pluginId);\n        await refreshSkills({ force: true });\n        await refreshCloudOrgMarketplaces({ force: true });\n        void refreshPendingCloudPluginChanges();\n        return {\n          ok: true,\n          message: `Removed ${result.item.name}.`,\n        };\n      }\n\n      const imported = snapshot.importedCloudPlugins[pluginId];\n      if (!imported) throw new Error(\"Marketplace package is not installed in this workspace.\");\n\n      const removedMcpNames: string[] = [];\n      const fileDeletes: Array<{ path: string; recursive?: boolean }> = [];\n      for (const file of imported.files) {\n        const mcpName = file.objectType === \"mcp\" ? cloudPluginMcpNameFromPath(file.path) : null;\n        if (mcpName) {\n          removedMcpNames.push(mcpName);\n          continue;\n        }\n        if (!file.path.startsWith(\".opencode/\")) continue;\n        const skillDir = file.path.match(/^(\\.opencode\\/skills\\/[^/]+\\/[^/]+)\\/SKILL\\.md$/)?.[1];\n        fileDeletes.push(skillDir ? { path: skillDir, recursive: true } : { path: file.path });\n      }\n      await Promise.all(removedMcpNames.map((name) => deletePluginMcpConfig(name)));\n      await deletePluginWorkspaceFiles(fileDeletes);\n\n      const nextPlugins = { ...snapshot.importedCloudPlugins };\n      delete nextPlugins[pluginId];","sourceCodeStart":1319,"sourceCodeEnd":1355,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/apps/app/src/react-app/domains/settings/state/extensions-store.ts#L1319-L1355","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Reconnect to the OpenWork server so removal goes through the server path (openworkClient branch), which does not need the local record.","Refresh the extensions store / re-fetch imported cloud plugins so the local registry is current, then retry.","Verify the pluginId against the keys of snapshot.importedCloudPlugins before calling remove.","If the record is genuinely stale, clear the persisted imported-cloud-plugins state so the UI stops offering the removal."],"exampleFix":"// before\nawait store.removeCloudOrgPlugin(pluginId);\n// after\nconst installed = useExtensionsStore.getState().importedCloudPlugins[pluginId];\nif (!installed) {\n  toast('Plugin is no longer installed.');\n  refreshCloudInventory();\n  return;\n}\nawait store.removeCloudOrgPlugin(pluginId);","handlingStrategy":"validation","validationCode":"const installed = store.snapshot.importedCloudPlugins[pluginId];\nif (!installed && !serverConnected) {\n  // skip local removal; refresh inventory instead\n}","typeGuard":"function isImportedCloudPlugin(\n  registry: Record<string, unknown>, pluginId: string,\n): boolean {\n  return Object.prototype.hasOwnProperty.call(registry, pluginId) && !!registry[pluginId];\n}","tryCatchPattern":"try {\n  await store.removeCloudOrgPlugin(pluginId);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('not installed in this workspace')) {\n    await refreshCloudInventory(); // heal stale state\n  } else throw e;\n}","preventionTips":["Refresh imported-cloud-plugin registry before rendering remove buttons","Clear registry entries on workspace switch","Treat local registry as a cache that can go stale","Confirm removal intent against the live registry"],"tags":["plugins","state","marketplace"],"backgroundTag":"resource-not-found","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}