{"record":{"id":"62e95c2154935e40","repo":"flipped-aurora/gin-vue-admin","slug":"error-62e95c","errorCode":null,"errorMessage":"已存在同名插件，请自行手动安装","messagePattern":"已存在同名插件，请自行手动安装","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/auto_code_plugin.go","lineNumber":156,"sourceCode":"\t}\n\n\treturn 1, 1, err\n}\n\nfunc installation(path string, formPath string, toPath string) error {\n\tarr := strings.Split(filepath.ToSlash(path), \"/\")\n\tln := len(arr)\n\tif ln < 3 {\n\t\treturn errors.New(\"arr\")\n\t}\n\tname := arr[ln-3]\n\n\tvar form = filepath.Join(global.GVA_CONFIG.AutoCode.Root, formPath, path)\n\tvar to = filepath.Join(global.GVA_CONFIG.AutoCode.Root, toPath, \"plugin\")\n\t_, err := os.Stat(to + name)\n\tif err == nil {\n\t\tzap.L().Error(\"autoPath 已存在同名插件，请自行手动安装\", zap.String(\"to\", to))\n\t\treturn errors.New(toPath + \"已存在同名插件，请自行手动安装\")\n\t}\n\treturn cp.Copy(form, to, cp.Options{Skip: skipMacSpecialDocument})\n}\n\nfunc (s *autoCodePlugin) installSubPlugin(file *multipart.FileHeader, parentPlugin string) (web, server int, err error) {\n\tserverRoot, err := utils.JoinWithinRoot(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server)\n\tif err != nil {\n\t\treturn -1, -1, err\n\t}\n\tif err = os.MkdirAll(serverRoot, 0755); err != nil {\n\t\treturn -1, -1, err\n\t}\n\ttempDir, err := os.MkdirTemp(serverRoot, \"gva-plugin-\")\n\tif err != nil {\n\t\treturn -1, -1, err\n\t}\n\tdefer os.RemoveAll(tempDir)\n","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/auto_code_plugin.go#L138-L174","documentation":"installation() refuses to copy a plugin when the destination (AutoCode.Root + toPath + 'plugin' + name) already exists on disk (os.Stat succeeds). This prevents overwriting an already-installed server or web plugin; the message includes toPath to say which side (server/web) collided.","triggerScenarios":"Installing the same plugin zip twice; installing a different plugin whose directory name equals an existing one in server/plugin/ or web/src/plugin/.","commonSituations":"Re-running an install script after a partial failure; two vendors shipping plugins with the same directory name; forgetting the plugin was installed on this environment.","solutions":["Delete or rename the existing plugin directory at the reported destination, then re-run the install.","If updating an existing plugin, use the plugin upgrade/manual-replace flow instead of first-time install.","Check the plugin's package name in enter.go and rename your new plugin to a unique directory name."],"exampleFix":"// before\nserver/plugin/email/  (already exists) -> install 'email' again fails\n// after\nrm -rf server/plugin/email web/src/plugin/email  # or rename new plugin\n# then re-run install","handlingStrategy":"validation","validationCode":"const target = `server/plugin/${pluginName}`\nif (fs.existsSync(target) || fs.existsSync(`web/src/plugin/${pluginName}`)) {\n  throw new Error('已存在同名插件，请自行手动安装')\n}","typeGuard":null,"tryCatchPattern":"_, _, err := pluginService.Install(file)\nif err != nil && strings.Contains(err.Error(), \"已存在同名插件\") {\n    // prompt user to remove/rename existing plugin, or treat as update via manual copy\n    return err\n}","preventionTips":["Check target directories for name collisions before installing a plugin.","Namespace plugin directory names with your org prefix to reduce clashes.","For upgrades, manually remove the old plugin directory (and its enter.go registration) before installing."],"tags":["plugin","filesystem-conflict","duplicate"],"backgroundTag":"destination-already-exists","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}