{"record":{"id":"f4dcac6b9619b0e8","repo":"Molunerfinn/PicGo","slug":"toggle-plugin-failed","errorCode":null,"errorMessage":"Toggle plugin failed","messagePattern":"Toggle plugin failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/renderer/store/plugins/actions.ts","lineNumber":204,"sourceCode":"        throw new Error(result.errMsg || result.body || 'Install plugin failed')\n      }\n\n      await appActions.hydrateAppState()\n      const installedPlugins = await pluginsAdapter.getInstalledPlugins()\n      pluginStoreActions.setInstalledPlugins(installedPlugins.map(mapInstalledPluginItem))\n      toast.success(i18n.t('PLUGIN_INSTALL_SUCCEED'))\n    } finally {\n      pluginStoreActions.setMutating(fullName, false)\n    }\n  },\n  async setPluginEnabled (fullName: string, enabled: boolean) {\n    pluginStoreActions.setMutating(fullName, true)\n\n    try {\n      const result = await pluginsAdapter.togglePluginEnabled(fullName, enabled)\n\n      if (!result.success) {\n        throw new Error(result.error || 'Toggle plugin failed')\n      }\n\n      await appActions.hydrateAppState()\n      const installedPlugins = await pluginsAdapter.getInstalledPlugins()\n      pluginStoreActions.setInstalledPlugins(installedPlugins.map(mapInstalledPluginItem))\n      toast.success(i18n.t(enabled ? 'ENABLE_PLUGIN' : 'DISABLE_PLUGIN'))\n    } finally {\n      pluginStoreActions.setMutating(fullName, false)\n    }\n  },\n  async updatePlugin (fullName: string) {\n    pluginStoreActions.setMutating(fullName, true)\n\n    try {\n      const result = await pluginsAdapter.updatePlugin(fullName)\n      if (!result.success) {\n        throw new Error(result.error || 'Update plugin failed')\n      }","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/Molunerfinn/PicGo/blob/07ec7068a5512344da093d49a8408fa63ba3421e/src/renderer/store/plugins/actions.ts#L186-L222","documentation":"setPluginEnabled throws when the ENABLE_PLUGIN/DISABLE_PLUGIN RPC via pluginsAdapter.togglePluginEnabled returns success:false, using result.error or the fallback 'Toggle plugin failed'. The surrounding try/catch resets the mutating flag and the toast confirms only on success.","triggerScenarios":"The main-process enable/disable handler fails: plugin not actually installed (removed on disk after list was cached), plugin's module fails to load/unload, internal handler error, or unknown fullName passed in.","commonSituations":"Toggling a plugin whose node_modules entry was deleted externally; stale UI list after manual filesystem changes; plugin with a broken main entry that cannot be enabled; race where two toggles run for the same plugin.","solutions":["Check result.error in the thrown message for the handler's specific failure.","Refresh the installed plugin list (pluginsAdapter.getInstalledPlugins) to ensure the fullName still exists.","Reinstall the plugin if it was removed or corrupted on disk, then retry the toggle.","Avoid concurrent toggles on the same plugin; wait for the mutating flag to clear."],"exampleFix":"// before\nconst result = await pluginsAdapter.togglePluginEnabled(fullName, enabled)\nif (!result.success) {\n  throw new Error(result.error || 'Toggle plugin failed')\n}\n// after\nconst installed = await pluginsAdapter.getInstalledPlugins()\nif (!installed.some(p => p.fullName === fullName)) {\n  toast.error(i18n.t('PLUGIN_NOT_FOUND'))\n  return\n}\nconst result = await pluginsAdapter.togglePluginEnabled(fullName, enabled)\nif (!result.success) {\n  throw new Error(result.error || i18n.t('PLUGIN_TOGGLE_FAILED'))\n}","handlingStrategy":"validation","validationCode":"const installed = useAppStore.getState().pluginsInstalled\nif (!installed.some(p => p.fullName === fullName)) {\n  toast.error(i18n.t('PLUGIN_NOT_FOUND'))\n  return\n}\nif (installed.find(p => p.fullName === fullName)?.enabled === enabled) {\n  return // already in the desired state, skip the RPC\n}","typeGuard":"function isToggleSuccess(r: { success: boolean, error?: string }): r is { success: true } {\n  return r.success === true\n}","tryCatchPattern":"try {\n  await pluginStoreActions.setPluginEnabled(fullName, enabled)\n} catch (e) {\n  toast.error(e instanceof Error ? e.message : i18n.t('PLUGIN_TOGGLE_FAILED'))\n  pluginStoreActions.setMutating(fullName, false)\n}","preventionTips":["Only render toggle switches for plugins present in the hydrated installed list.","Skip no-op toggles where the plugin already has the target enabled state.","Refresh the installed list after external filesystem changes.","Serialize toggles per plugin using the mutating flag to avoid races."],"tags":["plugin","rpc","state"],"backgroundTag":"plugin-toggle-failed","analyzedSha":"07ec7068a5512344da093d49a8408fa63ba3421e","analyzedAt":"2026-08-30T01:45:22.289Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}