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 {
				// 获取该菜单及其所有子菜单的ID

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Manually remove the plugin's import and RegisterPlugin call from the register file, then finish cleanup
  2. Check the register file parses as valid Go (gofmt/go build) and has the expected structure
  3. Ensure the server process can write the register file (permissions)
  4. If the import entry is already absent, treat the plugin as unregistered and verify the build
  5. 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

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


AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31). Data as JSON: /api/errors/9b8dac9c4e0a4bb8. Report an issue: GitHub.