{"record":{"id":"7cd7880aadbc45d9","repo":"Molunerfinn/PicGo","slug":"failed-to-delete-provider-config","errorCode":null,"errorMessage":"Failed to delete provider config","messagePattern":"Failed to delete provider config","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/renderer/adapters/providers.ts","lineNumber":39,"sourceCode":"    const result = await invokeRPC<IUploaderConfigItem>(IRPCActionType.GET_PICBED_CONFIG_LIST, type)\n    if (!result.success) {\n      throw new Error(result.error || 'Failed to load provider configs')\n    }\n\n    return result.data\n  },\n  async selectProviderConfig (type: string, configName: string) {\n    const result = await invokeRPC<string>(IRPCActionType.SELECT_UPLOADER, type, configName)\n    if (!result.success) {\n      throw new Error(result.error || 'Failed to select provider config')\n    }\n\n    return result.data\n  },\n  async deleteProviderConfig (type: string, configName: string) {\n    const result = await invokeRPC<IUploaderConfigItem>(IRPCActionType.DELETE_PICBED_CONFIG, type, configName)\n    if (!result.success) {\n      throw new Error(result.error || 'Failed to delete provider config')\n    }\n\n    return result.data\n  },\n  async copyProviderConfig (type: string, configName: string, newConfigName: string) {\n    const result = await invokeRPC<IUploaderConfigItem>(IRPCActionType.COPY_UPLOADER_CONFIG, type, configName, newConfigName)\n    if (!result.success) {\n      throw new Error(result.error || 'Failed to copy provider config')\n    }\n\n    return result.data\n  },\n  async saveProviderConfig (type: string, configId: string, values: IStringKeyMap) {\n    const result = await invokeRPC<boolean>(IRPCActionType.UPDATE_UPLOADER_CONFIG, type, configId, values)\n    if (!result.success) {\n      throw new Error(result.error || 'Failed to save provider config')\n    }\n","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/Molunerfinn/PicGo/blob/07ec7068a5512344da093d49a8408fa63ba3421e/src/renderer/adapters/providers.ts#L21-L57","documentation":"deleteProviderConfig sends IRPCActionType.DELETE_PICBED_CONFIG and throws when the RPC reports failure. The main handler (src/main/events/rpc/routes/config.ts:53) refuses to delete when only one config remains (TIPS_UPLOADER_CONFIG_CANNOT_DELETE_LAST) and picgo.uploaderConfig.remove(type, configName) can also throw if the named config does not exist. This guard prevents leaving a picbed type with zero configs.","triggerScenarios":"Deleting the last remaining config of an uploader type; deleting a configName that was already removed or renamed elsewhere; passing an unknown type.","commonSituations":"User tries to remove their only configured uploader; two settings windows operate on the same config simultaneously; stale UI list after a rename; programmatic cleanup scripts hitting the final config.","solutions":["Create a second config for that uploader type before deleting the last one (the main process enforces at least one config)","Refresh the config list and confirm the configName still exists before calling delete","Read result.error for the specific main-process message (e.g. cannot delete last config)","Retry after resyncing the settings window if the failure came from stale renderer state"],"exampleFix":"// before\nawait deleteProviderConfig(type, name)\n// after\nconst { configList } = await getProviderConfigList(type)\nif (configList.length > 1) await deleteProviderConfig(type, name)","handlingStrategy":"validation","validationCode":"const { configList } = await getProviderConfigList(type)\nif (configList.length <= 1) throw new Error('cannot delete the last config of this uploader')\nif (!configList.some(c => c._configName === configName)) throw new Error('config not found')","typeGuard":"function isDeletable(list: IUploaderConfigItem[], name: string): boolean { return list.length > 1 && list.some(c => c._configName === name) }","tryCatchPattern":"try {\n  await deleteProviderConfig(type, configName)\n} catch (e) {\n  // main enforces keeping the last config; surface its localized message\n  const msg = (e as Error).message\n  showNotification(msg || $T('TIPS_DELETE_CONFIG_FAILED'))\n  await refreshConfigList(type)\n}","preventionTips":["Disable the delete button in UI when only one config remains","Refresh the list before each delete to avoid stale names","Show a confirmation dialog before deleting","Never script deletion down to the final config"],"tags":["ipc","rpc","config","validation"],"backgroundTag":"rpc-failed-result","analyzedSha":"07ec7068a5512344da093d49a8408fa63ba3421e","analyzedAt":"2026-08-30T01:45:22.289Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}