flipped-aurora/gin-vue-admin · error

plugin结构异常,缺少plugin/%s/plugin.go

Error message

plugin结构异常,缺少plugin/%s/plugin.go

What it means

checkPackage validates plugin-type generation: the target plugin must already have plugin/<Pkg>/plugin.go (the plugin entry aggregating its routes/apis) under the configured server root. If missing, Create aborts with this error. It prevents generating code into a plugin that was never initialized.

Source

Thrown at server/service/system/auto_code_template.go:56

		_, err = os.Stat(apiEnter)
		if err != nil {
			return fmt.Errorf("package结构异常,缺少api/v1/%s/enter.go", Pkg)
		}
		serviceEnter := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "service", Pkg, "enter.go")
		_, err = os.Stat(serviceEnter)
		if err != nil {
			return fmt.Errorf("package结构异常,缺少service/%s/enter.go", Pkg)
		}
		routerEnter := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "router", Pkg, "enter.go")
		_, err = os.Stat(routerEnter)
		if err != nil {
			return fmt.Errorf("package结构异常,缺少router/%s/enter.go", Pkg)
		}
	case "plugin":
		pluginEnter := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "plugin", Pkg, "plugin.go")
		_, err = os.Stat(pluginEnter)
		if err != nil {
			return fmt.Errorf("plugin结构异常,缺少plugin/%s/plugin.go", Pkg)
		}
	}
	return nil
}

// Create 创建生成自动化代码
func (s *autoCodeTemplate) Create(ctx context.Context, info request.AutoCode) error {
	autoCodeCreateMu.Lock()
	defer autoCodeCreateMu.Unlock()

	// Frontend files are published last, but their Vite refresh may still cancel
	// the HTTP request before the handler returns. The accepted create task must finish.
	createCtx := autoCodeCreateContext(ctx)
	var autoPkg model.SysAutoCodePackage
	err := global.GVA_DB.WithContext(createCtx).Where("package_name = ?", info.Package).First(&autoPkg).Error
	if err != nil {
		return errors.Wrap(err, "查询包失败!")
	}

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Initialize the plugin skeleton so server/plugin/<Pkg>/plugin.go exists (public Plugin variable, Router registration) and register it in plugin/initialize.
  2. Check the plugin name spelling matches the server/plugin directory.
  3. Verify autoCode.root/server config resolves to the real server tree.
  4. Follow the documented plugin v2 structure (initialize/router.go, enter.go aggregation) before generating code into it.

Example fix

// before
server/plugin/mytool/  // no plugin.go
// after
// server/plugin/mytool/plugin.go
type Mytool struct{}
var Plugin = new(Mytool)
func (p *Mytool) Register(group *gin.RouterGroup) {}
Defensive patterns

Strategy: validation

Validate before calling

pluginEnter := filepath.Join(cfg.AutoCode.Root, cfg.AutoCode.Server, "plugin", pkg, "plugin.go")
if _, err := os.Stat(pluginEnter); err != nil {
    return fmt.Errorf("initialize server/plugin/%s (plugin.go) before generating", pkg)
}

Try / catch

if err := s.Create(info); err != nil {
    if strings.Contains(err.Error(), "缺少plugin") {
        // initialize the plugin skeleton then retry
    }
    return err
}

Prevention

When it happens

Trigger: autoCodeTemplate.Create with template="plugin" and a Pkg whose server/plugin/<Pkg>/plugin.go does not exist — plugin directory never created or named differently.

Common situations: Typo in plugin name in the generator form; plugin created only in web/src/plugin but not server/plugin; plugin scaffold deleted; autoCode.root/server config pointing at a different checkout.

Related errors


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