flipped-aurora/gin-vue-admin · critical

sys_apis表数据初始化失败!

Error message

sys_apis表数据初始化失败!

What it means

During gin-vue-admin's database initialization, the initApi initializer bulk-inserts the seeded sys_apis rows (the full API registry used by Casbin/menu binding). The GORM Create call failed, and pkg/errors.Wrap attached this message to the underlying DB error. Without these rows the API management page and permission binding have no data.

Solutions

  1. Check the wrapped cause in the logs for the real driver error (duplicate key, unknown column, access denied).
  2. If re-initializing, drop the database (or truncate sys_apis) so the seed insert starts clean.
  3. Verify sys_apis schema matches the current version; let GORM AutoMigrate recreate it during init.
  4. Confirm the configured DB user has INSERT privilege and the server is reachable/has disk space.
  5. Re-run InitDB after fixing; success is silent (returns next context).

Example fix

// before: init fails on leftover rows
// duplicate Path+Method unique conflicts on re-init
// after: wipe the target database (or table) before re-running initdb
DROP DATABASE gva;
CREATE DATABASE gva;
// then POST /init/initdb again
Defensive patterns

Strategy: try-catch

Validate before calling

// before calling initdb, check DB is reachable and sys_apis is empty
rows, err := db.Exec("SELECT COUNT(*) FROM sys_apis")
if err != nil { /* table missing or DB unreachable - fix before init */ }

Try / catch

if err := initdb(); err != nil {
    var wrapped interface{ Unwrap() error }
    if errors.As(err, &cause) {
        log.Printf("sys_apis seed failed: %v", cause) // duplicate key / schema / privilege
    }
    return fmt.Errorf("init aborted: %w", err)
}

Prevention

When it happens

Trigger: Running InitDB (first-time install or re-initialization) when the INSERT into sys_apis fails - e.g. the table exists with conflicting rows (duplicate primary keys), the DB connection drops mid-init, the table schema is stale (missing columns added in a newer version), or the DB user lacks INSERT privilege.

Common situations: Re-running init on a partially initialized database where old sys_apis rows remain; upgrading gin-vue-admin against an old schema that was never migrated; MySQL/PG credentials without write access; disk-full or connection-timeout during init.

Related errors


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

Appendix: source

Thrown at server/source/system/api.go:254

		{ApiGroup: "参数管理", Method: "DELETE", Path: "/sysParams/deleteSysParamsByIds", Description: "批量删除参数"},
		{ApiGroup: "参数管理", Method: "PUT", Path: "/sysParams/updateSysParams", Description: "更新参数"},
		{ApiGroup: "参数管理", Method: "GET", Path: "/sysParams/findSysParams", Description: "根据ID获取参数"},
		{ApiGroup: "参数管理", Method: "GET", Path: "/sysParams/getSysParamsList", Description: "获取参数列表"},
		{ApiGroup: "参数管理", Method: "GET", Path: "/sysParams/getSysParam", Description: "获取参数列表"},
		{ApiGroup: "媒体库分类", Method: "GET", Path: "/attachmentCategory/getCategoryList", Description: "分类列表"},
		{ApiGroup: "媒体库分类", Method: "POST", Path: "/attachmentCategory/addCategory", Description: "添加/编辑分类"},
		{ApiGroup: "媒体库分类", Method: "POST", Path: "/attachmentCategory/deleteCategory", Description: "删除分类"},

		{ApiGroup: "版本控制", Method: "GET", Path: "/sysVersion/findSysVersion", Description: "获取单一版本"},
		{ApiGroup: "版本控制", Method: "GET", Path: "/sysVersion/getSysVersionList", Description: "获取版本列表"},
		{ApiGroup: "版本控制", Method: "GET", Path: "/sysVersion/downloadVersionJson", Description: "下载版本json"},
		{ApiGroup: "版本控制", Method: "POST", Path: "/sysVersion/exportVersion", Description: "创建版本"},
		{ApiGroup: "版本控制", Method: "POST", Path: "/sysVersion/importVersion", Description: "同步版本"},
		{ApiGroup: "版本控制", Method: "DELETE", Path: "/sysVersion/deleteSysVersion", Description: "删除版本"},
		{ApiGroup: "版本控制", Method: "DELETE", Path: "/sysVersion/deleteSysVersionByIds", Description: "批量删除版本"},
	}
	if err := db.Create(&entities).Error; err != nil {
		return ctx, errors.Wrap(err, sysModel.SysApi{}.TableName()+"表数据初始化失败!")
	}
	next := context.WithValue(ctx, i.InitializerName(), entities)
	return next, nil
}

func (i *initApi) DataInserted(ctx context.Context) bool {
	db, ok := ctx.Value("db").(*gorm.DB)
	if !ok {
		return false
	}
	if errors.Is(db.Where("path = ? AND method = ?", "/authorityBtn/canRemoveAuthorityBtn", "POST").
		First(&sysModel.SysApi{}).Error, gorm.ErrRecordNotFound) {
		return false
	}
	return true
}

View on GitHub (pinned to 3136500ef3)