flipped-aurora/gin-vue-admin · error

删除后端插件目录失败

Error message

删除后端插件目录失败

What it means

In AutoCodePluginService.Remove, for pluginType 'server' or 'full', os.RemoveAll(serverDir) deletes the plugin's backend directory under server/plugin/<name>. Failure is wrapped as '删除后端插件目录失败'. This happens after the frontend step and before the plugin registration import is removed.

Source

Thrown at server/service/system/auto_code_plugin.go:931

		serverDir, err = pluginPath(global.GVA_CONFIG.AutoCode.Server, pluginName)
		if err != nil {
			return err
		}
	}

	// 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. 删除菜单 (递归删除)

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Stop any process using files under server/plugin/<pluginName> and retry
  2. Fix ownership/permissions: chown -R or chmod u+w server/plugin/<pluginName>
  3. Check that the volume containing server/plugin is writable
  4. If partially deleted, clean remnants manually then retry Remove
  5. Verify AutoCode.Server config points at the real server root

Example fix

// before
$ rm -rf server/plugin/foo  # permission denied
// after
$ sudo chown -R $(whoami) server/plugin/foo && retry
Defensive patterns

Strategy: validation

Validate before calling

serverDir := filepath.Join("server/plugin", pluginName)
if fi, err := os.Stat(serverDir); err == nil && !fi.IsDir() {
    return errors.New("plugin path is not a directory")
}
if err := unix.Access(filepath.Dir(serverDir), unix.W_OK); err != nil {
    return fmt.Errorf("cannot delete under server/plugin: %w", err)
}

Try / catch

err := pluginSvc.Remove(ctx, pluginName, "server")
if err != nil && strings.Contains(err.Error(), "删除后端插件目录失败") {
    log.Printf("underlying: %v", errors.Unwrap(err)) // fs.ErrPermission / fs.ErrNotExist
}

Prevention

When it happens

Trigger: Calling Remove for a server/full plugin while the server/plugin/<name> directory cannot be deleted: permissions, binary/compiled artifacts locked by a running build, or read-only mount.

Common situations: Go build cache or a compiled plugin binary still running/locked; container with read-only server/plugin volume; wrong user (server not run as directory owner); NFS/Windows share lock issues.

Related errors


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