flipped-aurora/gin-vue-admin · error
移除插件注册失败
Error message
移除插件注册失败
What it means
After deleting the plugin's server directory during Remove, the service strips the plugin's import registration from the aggregation file (removePluginRegisterImport, an AST edit of the plugin registry). If that code edit/write fails, the error is wrapped as '移除插件注册失败'. The plugin directories may already be gone, leaving the codebase referencing a deleted package.
Source
Thrown at server/service/system/auto_code_plugin.go:936
// 1. 删除前端代码
if pluginType == "web" || pluginType == "full" {
err = os.RemoveAll(webDir)
if err != nil {
return errors.Wrap(err, "删除前端插件目录失败")
}
}
// 2. 删除后端代码
if pluginType == "server" || pluginType == "full" {
err = os.RemoveAll(serverDir)
if err != nil {
return errors.Wrap(err, "删除后端插件目录失败")
}
// 移除注册
if err = removePluginRegisterImport(pluginName); err != nil {
return errors.Wrap(err, "移除插件注册失败")
}
}
// 通过utils 获取 api 菜单 字典
apis, menus, dicts := pluginUtils.GetPluginData(pluginName)
// DB 清理阶段脱离请求取消:上面 1/2 的文件删除不可逆且已完成,若客户端此刻
// 断连,请求 ctx 取消会让下面的清理全部快速失败(循环内错误只记日志不中断),
// 菜单/API/字典静默残留;且进程重启后插件不再注册,GetPluginData 拿不到
// 数据,孤儿再也无法通过 Remove 清掉。WithoutCancel 保留链路字段、剥离取消。
cleanupCtx := context.WithoutCancel(ctx)
// 3. 删除菜单 (递归删除)
if len(menus) > 0 {
for _, menu := range menus {
var dbMenu system.SysBaseMenu
if err := global.GVA_DB.WithContext(cleanupCtx).Where("name = ?", menu.Name).First(&dbMenu).Error; err == nil {
// 获取该菜单及其所有子菜单的IDView on GitHub (pinned to 3136500ef3)
Solutions
- Manually remove the plugin's import and RegisterPlugin call from the register file, then finish cleanup
- Check the register file parses as valid Go (gofmt/go build) and has the expected structure
- Ensure the server process can write the register file (permissions)
- If the import entry is already absent, treat the plugin as unregistered and verify the build
- Re-create the plugin skeleton via the code generator, then uninstall cleanly
Example fix
// before (manually mangled register file, syntax broken) // after: restore valid Go and retry $ gofmt -w server/initialize/plugin*.go && go build ./...
Defensive patterns
Strategy: try-catch
Try / catch
err := pluginSvc.Remove(ctx, pluginName, "full")
if err != nil && strings.Contains(err.Error(), "移除插件注册失败") {
// directories may already be deleted; manually clean the register file
// (remove import + RegisterPlugin call) then verify the build:
// go build ./...
} Prevention
- Never hand-edit the plugin register file; keep gofmt-clean syntax
- Keep the register file under version control so it can be restored
- Verify `go build ./...` passes after any manual register edits
- Check the plugin actually has a registration entry before removal
When it happens
Trigger: removePluginRegisterImport fails because the register file is missing, read-only, the plugin name has no matching import entry, or AST parse/format of the register file fails after directories were already deleted.
Common situations: User manually edited the plugin register file (e.g. server/initialize/plugin* or plugin register go file) breaking the expected import format; register file deleted; server process lacks write permission to it; plugin installed but never registered.
Related errors
- read file failed: %w
- parse file failed: %w
- no function encloses line %d in %s
- invalid offsets for function: start=%d end=%d len=%d
- gorm 注入目标不能为空
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/9b8dac9c4e0a4bb8.
Report an issue: GitHub.