flipped-aurora/gin-vue-admin · error
expect struct
Error message
expect struct
What it means
Verify in server/utils/validator.go is a reflection-based struct validator that reads custom `mj:` tags from each struct field. It first reflects the input with reflect.TypeOf/reflect.ValueOf and requires the dynamic kind to be reflect.Struct. If a caller passes a non-struct (nil, pointer-to-something, map, slice, or basic type), Verify returns errors.New("expect struct") instead of validating. The library throws this to prevent reflect panics like NumField on a non-struct kind.
Source
Thrown at server/utils/validator.go:133
//@param: st interface{}, roleMap Rules(入参实例,规则map)
//@return: err error
func Verify(st interface{}, roleMap Rules) (err error) {
compareMap := map[string]bool{
"lt": true,
"le": true,
"eq": true,
"ne": true,
"ge": true,
"gt": true,
}
typ := reflect.TypeOf(st)
val := reflect.ValueOf(st) // 获取reflect.Type类型
kd := val.Kind() // 获取到st对应的类别
if kd != reflect.Struct {
return errors.New("expect struct")
}
num := val.NumField()
// 遍历结构体的所有字段
for i := 0; i < num; i++ {
tagVal := typ.Field(i)
val := val.Field(i)
// 只递归进【匿名内嵌】结构体(如 global.GVA_MODEL / request.PageInfo):
// 递归的唯一目的是够到内嵌提升上来的字段(如 IdVerify 的 ID、PageInfoVerify 的 Page)。
// 具名关联字段(User/Dept/Meta 等)是独立业务对象,不属于当前结构体自身,不应被扫描——
// 否则关联对象内嵌的 GVA_MODEL.ID 恒为 0,会让 IdVerify 误报"ID值不能为空"。
// 需要单独校验某个具名子结构时,调用方直接 Verify(x.Sub, rule)(项目既有用法)。
if tagVal.Anonymous && tagVal.Type.Kind() == reflect.Struct {
if err = Verify(val.Interface(), roleMap); err != nil {
return err
}
}
if len(roleMap[tagVal.Name]) > 0 {
for _, v := range roleMap[tagVal.Name] {View on GitHub (pinned to 3136500ef3)
Solutions
- Pass the struct by value, not a pointer: utils.Verify(req, roleMap) instead of utils.Verify(&req, roleMap).
- Check for nil and dereference pointers before calling: if st != nil { st = reflect.ValueOf(st).Elem().Interface() }.
- Ensure the variable actually holds a struct value, not an interface{} wrapping a map or basic type; log reflect.TypeOf(st) to confirm.
- If you control the call site generically, guard with reflect.TypeOf(st).Kind() == reflect.Struct before invoking Verify.
Example fix
// before
req := &model.SysUser{}
if err := utils.Verify(req, utils.Rules{}); err != nil { ... }
// after
req := model.SysUser{}
if err := utils.Verify(req, utils.Rules{}); err != nil { ... } Defensive patterns
Strategy: validation
Validate before calling
if st == nil || reflect.TypeOf(st).Kind() != reflect.Struct {
return errors.New("Verify requires a struct value (not pointer/map/nil)")
} Type guard
func isStruct(v interface{}) bool {
if v == nil { return false }
return reflect.TypeOf(v).Kind() == reflect.Struct
} Prevention
- Always pass struct values, never pointers, to utils.Verify
- In generic helpers, assert reflect kind Struct before calling Verify
- Add a unit test exercising Verify with the real request struct
When it happens
Trigger: Calling utils.Verify(st, roleMap) where st is nil, a pointer (e.g. &req), a map[string]interface{}, a slice, or a primitive such as a string or int. Note that in Go, reflect.ValueOf(&req{}).Kind() is reflect.Ptr, so even a pointer to a struct triggers this error.
Common situations: Developers pass a request-binding pointer (form.ShouldBindJSON returns *Struct) straight into Verify, pass an uninitialized interface{} variable, or call Verify in a generic helper where the argument type is interface{} and nothing guarantees a struct value was stored.
Related errors
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/966b08e57c1c3135.
Report an issue: GitHub.