Skip to content

[Bug]: Plugin install button changes back to Install instead of showing Uninstall after installation #13094

@EurFelux

Description

@EurFelux

Thank you for taking the time to fill out this bug report!
Before submitting this issue, please make sure that you have understood the FAQ and Knowledge Science

  • I understand that issues are for feedback and problem solving, not for complaining in the comment section, and will provide as much information as possible to help solve the problem.
  • My issue is not listed in the FAQ.
  • I've looked at pinned issues and searched for existing Open Issues, Closed Issues, and Discussions, no similar issue or discussion was found.
  • I've filled in short, clear headings so that a rough idea of what to expect when flipping through the list developers can quickly identify of issues. And not "a suggestion", "stuck", etc.
  • I've confirmed that I am using the latest version of Cherry Studio.

Platform

macOS

Version

latest

Bug Description

In the PluginBrowser component, after successfully installing a plugin, the loading button does not change to "Uninstall" - it changes back to "Install" instead. This is caused by the installed state not being refreshed in time.

Root Cause

The root cause is in usePlugins.ts, in the executeAction function:

const executeAction = useCallback(
  async <TResult>(...): Promise<...> => {
    setLoading(true)
    try {
      const result = await action()
      if (result.success) {
        onSuccess?.()  // Called WITHOUT await!
        return { success: true, data: result.data as TResult }
      }
      // ...
    } finally {
      setLoading(false)
    }
  },
  [onSuccess]
)

The onSuccess?.() (which calls refresh()) is called without await, so when handleInstall awaits onInstall(), it only waits for the installation API to complete, not for the refresh to finish.

Timeline of the bug:

  1. User clicks Install → setLoading(true) in handleInstall
  2. await onInstall() completes → installation API done, but refresh() still running
  3. setLoading({ id: loadingKey, value: false }) executes immediately
  4. At this point, installedPlugins still has old data (refresh not complete)
  5. isPluginInstalled(plugin) returns false
  6. Button shows "Install" instead of "Uninstall"

Steps To Reproduce

  1. Go to the plugin browser in settings
  2. Find a plugin that is not installed
  3. Click the Install button
  4. Observe: After installation completes, the button changes back to "Install" instead of showing "Uninstall"

Expected Behavior

After successful installation, the button should change to "Uninstall" to indicate the plugin is now installed.

Additional Context

The same issue likely exists for uninstall operations.

Suggested Fix

In src/renderer/src/hooks/usePlugins.ts, change executeAction to await onSuccess?.():

if (result.success) {
  await onSuccess?.()  // Add await here!
  return { success: true, data: result.data as TResult }
}

This ensures that when onInstall() returns, the refresh() has already completed, and installedPlugins will have the latest data.

Related code location:

  • src/renderer/src/hooks/usePlugins.ts:59-80 (executeAction function)
  • src/renderer/src/pages/settings/AgentSettings/components/PluginsSettings/components/PluginBrowser.tsx:181-193

Metadata

Metadata

Assignees

No one assigned

    Labels

    BUGCategorizes issue or PR as related to a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions