{"record":{"id":"c2fe330dbadc4f84","repo":"flipped-aurora/gin-vue-admin","slug":"api-c2fe33","errorCode":null,"errorMessage":"存在相同api路径","messagePattern":"存在相同api路径","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"server/service/system/sys_api.go","lineNumber":289,"sourceCode":"\n//@author: [piexlmax](https://github.com/piexlmax)\n//@function: UpdateApi\n//@description: 根据id更新api\n//@param: api model.SysApi\n//@return: err error\n\nfunc (apiService *ApiService) UpdateApi(ctx context.Context, api system.SysApi) (err error) {\n\tvar oldA system.SysApi\n\terr = global.GVA_DB.WithContext(ctx).First(&oldA, \"id = ?\", api.ID).Error\n\tif oldA.Path != api.Path || oldA.Method != api.Method {\n\t\tvar duplicateApi system.SysApi\n\t\tif ferr := global.GVA_DB.WithContext(ctx).First(&duplicateApi, \"path = ? AND method = ?\", api.Path, api.Method).Error; ferr != nil {\n\t\t\tif !errors.Is(ferr, gorm.ErrRecordNotFound) {\n\t\t\t\treturn ferr\n\t\t\t}\n\t\t} else {\n\t\t\tif duplicateApi.ID != api.ID {\n\t\t\t\treturn errors.New(\"存在相同api路径\")\n\t\t\t}\n\t\t}\n\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n\n\terr = CasbinServiceApp.UpdateCasbinApi(ctx, oldA.Path, api.Path, oldA.Method, api.Method)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn global.GVA_DB.WithContext(ctx).Save(&api).Error\n}\n\n//@author: [piexlmax](https://github.com/piexlmax)\n//@function: DeleteApisByIds","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/sys_api.go#L271-L307","documentation":"UpdateApi guards against renaming an API's path/method into a collision with a different existing row. It loads a record matching the new path+method; if found and its primary key differs from the record being updated (duplicateApi.ID != api.ID), it returns \"存在相同api路径\". Updating a row to its own current path+method is allowed.","triggerScenarios":"Calling PUT /api/updateApi with a changed path or method that already exists on another sys_api row (different ID). E.g. editing API id=5 to path=/base/login method=POST when id=12 already has that pair.","commonSituations":"Merging two environment copies of the API table then editing entries; a typo causes the new path to equal another endpoint's path; bulk edits applied to multiple rows without deduplication.","solutions":["Pick a path+method pair not present in the sys_api table (check the API list page first).","If the two rows should be one, delete the other duplicate row and retry the update.","Ensure the ID in the update payload matches the row you intend to edit; stale frontend data can make the service compare against the wrong ID."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const dup = list.find(a => a.path === form.path && a.method === form.method)\nif (dup && dup.ID !== form.ID) throw new Error('目标 path+method 已被另一条记录占用 (ID=' + dup.ID + ')')","typeGuard":null,"tryCatchPattern":"try {\n  await updateApi(form)\n} catch (e) {\n  if (String(e?.msg).includes('存在相同api路径')) {\n    ElMessage.warning('其他 API 已使用该 path+method，请换一个或删除冲突记录')\n  } else { throw e }\n}","preventionTips":["Exclude the record's own ID when checking for collisions in the UI.","Refresh the API list before bulk edits so IDs in the payload are current.","Run a uniqueness check (path, method) over the whole table after imports.","Avoid copy-paste edits that only change the description while keeping a colliding path."],"tags":["duplicate-record","api-management","gorm","validation"],"backgroundTag":"duplicate-unique-key","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}