{"record":{"id":"1e39376d73249235","repo":"Molunerfinn/PicGo","slug":"tips-uploader-config-cannot-delete-last","errorCode":null,"errorMessage":"TIPS_UPLOADER_CONFIG_CANNOT_DELETE_LAST","messagePattern":"TIPS_UPLOADER_CONFIG_CANNOT_DELETE_LAST","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/main/events/rpc/routes/config.ts","lineNumber":58,"sourceCode":"  .add(IRPCActionType.GET_PICBED_CONFIG_LIST, async (args) => {\n    try {\n      const [type] = args as IGetUploaderConfigListArgs\n      const configList = picgo.uploaderConfig.getConfigList(type)\n      const activeConfig = picgo.uploaderConfig.getActiveConfig(type)\n      return ok({\n        configList,\n        defaultId: activeConfig?._id ?? ''\n      })\n    } catch (e) {\n      return fail(e)\n    }\n  })\n  .add(IRPCActionType.DELETE_PICBED_CONFIG, async (args) => {\n    try {\n      const [type, configName] = args as IDeleteUploaderConfigArgs\n      const existing = picgo.uploaderConfig.getConfigList(type)\n      if (existing.length <= 1) {\n        throw new Error(T('TIPS_UPLOADER_CONFIG_CANNOT_DELETE_LAST'))\n      }\n      picgo.uploaderConfig.remove(type, configName)\n      const configList = picgo.uploaderConfig.getConfigList(type)\n      const activeConfig = picgo.uploaderConfig.getActiveConfig(type)\n      notifyAppConfigUpdated()\n      return ok({\n        configList,\n        defaultId: activeConfig?._id ?? ''\n      })\n    } catch (e) {\n      return fail(e)\n    }\n  })\n  .add(IRPCActionType.COPY_UPLOADER_CONFIG, async (args) => {\n    try {\n      const [type, configName, newConfigName] = args as ICopyUploaderConfigArgs\n      picgo.uploaderConfig.copy(type, configName, newConfigName)\n      const configList = picgo.uploaderConfig.getConfigList(type)","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/Molunerfinn/PicGo/blob/07ec7068a5512344da093d49a8408fa63ba3421e/src/main/events/rpc/routes/config.ts#L40-L76","documentation":"The DELETE_PICBED_CONFIG RPC route refuses to delete when the uploader type has only one configuration left, throwing TIPS_UPLOADER_CONFIG_CANNOT_DELETE_LAST. At least one config per uploader type must always exist so an active uploader config remains resolvable. The message is an i18n key rendered for the user.","triggerScenarios":"Calling DELETE_PICBED_CONFIG with [type, configName] where picgo.uploaderConfig.getConfigList(type).length <= 1 — i.e. deleting the only config for that uploader type.","commonSituations":"User repeatedly deletes uploader profiles and reaches the last one; UI delete button not disabled when only one entry remains; batch cleanup scripts removing all configs of a type.","solutions":["Create a second config for the type before deleting the one you want removed","Switch to a different uploader type entirely instead of deleting the last config","In the UI, disable/hide the delete action when configList.length <= 1","If you truly need an empty list, clear config via config editing rather than the delete API"],"exampleFix":"// before\nawait deleteUploaderConfig(type, 'only-config') // throws if it's the last one\n// after\nawait addUploaderConfig(type, 'new-default')\nawait deleteUploaderConfig(type, 'only-config')","handlingStrategy":"validation","validationCode":"const list = await getUploaderConfigList(type)\nif (list.length <= 1) {\n  throw new Error('Cannot delete the last config for ' + type)\n}\nawait deleteUploaderConfig(type, configName)","typeGuard":null,"tryCatchPattern":"try {\n  await deleteUploaderConfig(type, configName)\n} catch (e) {\n  if (e.message.includes('CANNOT_DELETE_LAST')) {\n    notify('Create another config before deleting this one')\n  } else throw e\n}","preventionTips":["Check getConfigList(type).length > 1 before calling delete","Disable the delete button when only one config exists","Offer 'switch uploader type' as the alternative to deleting the last config"],"tags":["config","uploader","delete-constraint","business-rule"],"backgroundTag":"cannot-delete-last-item","analyzedSha":"07ec7068a5512344da093d49a8408fa63ba3421e","analyzedAt":"2026-08-30T01:45:22.289Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}