Molunerfinn/PicGo · error
Plugin not found
Error message
Plugin not found
What it means
savePluginConfig throws the literal 'Plugin not found' when the fullName being configured does not exist in the appStore's pluginsInstalled list. This is a client-side guard before computing the target config name — the plugin entry (with its config/transformer sections) is required to build the config payload.
Source
Thrown at src/renderer/store/plugins/actions.ts:274
toast.success(i18n.t('PLUGIN_UNINSTALL_SUCCEED'))
} finally {
pluginStoreActions.setMutating(fullName, false)
}
},
async savePluginConfig (
fullName: string,
section: PluginConfigSectionType,
values: Record<string, unknown>
) {
pluginStoreActions.setMutating(fullName, true)
try {
const installedPlugin = useAppStore.getState().pluginsInstalled.find(
(item) => item.fullName === fullName
)
if (!installedPlugin) {
throw new Error('Plugin not found')
}
const targetConfigName =
section === 'config'
? installedPlugin.config.plugin.fullName || installedPlugin.config.plugin.name
: installedPlugin.config.transformer.fullName || installedPlugin.config.transformer.name
await pluginsAdapter.savePluginConfig(
section === 'config' ? 'plugin' : 'transformer',
targetConfigName,
values as IStringKeyMap
)
await appActions.refreshAppConfig()
const installedPlugins = await pluginsAdapter.getInstalledPlugins()
pluginStoreActions.setInstalledPlugins(installedPlugins.map(mapInstalledPluginItem))
} finally {
pluginStoreActions.setMutating(fullName, false)
}View on GitHub (pinned to 07ec7068a5)
Solutions
- Verify the fullName matches an entry in the installed plugins list exactly (compare against mapInstalledPluginItem output).
- Ensure appActions.hydrateAppState()/getInstalledPlugins completed before rendering or saving plugin config UI.
- Strip or add the picgo-plugin- prefix consistently (see streamlinePluginName) when matching names.
- Refresh the installed list after any install/uninstall, then retry saving the config.
- Show a user-facing 'plugin not installed' toast instead of only throwing, so the dialog can close gracefully.
Example fix
// before
const installedPlugin = useAppStore.getState().pluginsInstalled.find(
(item) => item.fullName === fullName
)
if (!installedPlugin) {
throw new Error('Plugin not found')
}
// after
const installedPlugin = useAppStore.getState().pluginsInstalled.find(
(item) => item.fullName === fullName || `picgo-plugin-${item.fullName}` === fullName
)
if (!installedPlugin) {
toast.error(i18n.t('PLUGIN_NOT_FOUND'))
return
} Defensive patterns
Strategy: type-guard
Validate before calling
const installedPlugin = useAppStore.getState().pluginsInstalled.find(
(item) => item.fullName === fullName || `picgo-plugin-${item.fullName}` === fullName
)
if (!installedPlugin) {
toast.error(i18n.t('PLUGIN_NOT_FOUND'))
return
} Type guard
function findInstalledPlugin(list: IPicGoPlugin[], fullName: string): IPicGoPlugin | undefined {
return list.find(
(item) => item.fullName === fullName || item.fullName === fullName.replace(/^picgo-plugin-/, '')
)
} Try / catch
try {
await pluginStoreActions.savePluginConfig(fullName, section, data)
} catch (e) {
if (e instanceof Error && e.message === 'Plugin not found') {
toast.error(i18n.t('PLUGIN_NOT_FOUND'))
return
}
throw e
} Prevention
- Await appActions.hydrateAppState() before rendering plugin config forms so pluginsInstalled is populated.
- Normalize fullName with streamlinePluginName when matching stored entries.
- Close/disable config dialogs when the underlying plugin is uninstalled.
- Refresh the installed list after install/uninstall flows before allowing config saves.
When it happens
Trigger: savePluginConfig called with a fullName that is not in useAppStore.getState().pluginsInstalled: stale component state after the plugin was uninstalled elsewhere, misspelled fullName, plugin list not yet hydrated (hydrateAppState not awaited), or the name includes the picgo-plugin- prefix while the stored list uses the short name.
Common situations: Saving a plugin settings form after the plugin was uninstalled in another window/tab; rendering config UI before the installed-plugins fetch completes; mismatch between registry fullName (picgo-plugin-foo) and the shortened stored name (foo).
Related errors
- Transformer not found
- Toggle plugin failed
- ALBUM_URL_REWRITE_TEMP_RULE_REQUIRED
- Invalid URL rewrite regex pattern "${rule.match}": ${error i
- TIPS_UPLOADER_CONFIG_NAME_EMPTY
AI-assisted analysis of Molunerfinn/PicGo@07ec7068a5 (2026-08-30).
Data as JSON: /api/errors/130d8af56447c0d3.
Report an issue: GitHub.