flipped-aurora/gin-vue-admin · warning

值不能为空

Error message

值不能为空

What it means

Verify iterates struct fields and the rules loaded from the `mj:` tag (roleMap). When a rule contains "notEmpty" and isBlank(val) reports the field as blank (zero value, empty string, whitespace, or zero-length), it returns errors.New(fieldName + "值不能为空"), i.e. '<Field> value cannot be empty'. The library throws this so callers get a precise, field-named validation failure instead of letting an empty required value pass through.

Source

Thrown at server/utils/validator.go:155

	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] {
				switch {
				case v == "notEmpty":
					if isBlank(val) {
						return errors.New(tagVal.Name + "值不能为空")
					}
				case strings.Split(v, "=")[0] == "regexp":
					if !regexpMatch(strings.Split(v, "=")[1], val.String()) {
						return errors.New(tagVal.Name + "格式校验不通过")
					}
				case compareMap[strings.Split(v, "=")[0]]:
					if !compareVerify(val, v) {
						return errors.New(tagVal.Name + "长度或值不在合法范围," + v)
					}
				}
			}
		}
	}
	return nil
}

//@author: [piexlmax](https://github.com/piexlmax)
//@function: compareVerify

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Populate the required field before calling Verify, or return the field's error to the client and ask them to fill it in.
  2. Trim/normalize input and treat whitespace-only as missing on the frontend so users get earlier feedback.
  3. If the field is legitimately optional, remove "notEmpty" from its `mj:` tag instead of bypassing Verify.
  4. Bind the request with Gin binding first (binding:"required") so empty payloads fail at the HTTP layer with a standard message.

Example fix

// before
type Login struct { Username string `json:"username" mj:"notEmpty"` }
u := Login{}
utils.Verify(u, utils.Rules{}) // -> "Username值不能为空"

// after
u := Login{Username: "admin"}
if err := utils.Verify(u, utils.Rules{}); err != nil {
    c.String(400, err.Error())
}
Defensive patterns

Strategy: validation

Validate before calling

v := strings.TrimSpace(req.Username)
if v == "" {
    return errors.New("username is required")
}
req.Username = v
return utils.Verify(req, utils.Rules{})

Try / catch

if err := utils.Verify(req, utils.Rules{}); err != nil {
    c.JSON(400, gin.H{"msg": err.Error()})
    return
}

Prevention

When it happens

Trigger: Calling Verify on a struct whose `mj:"notEmpty"`-tagged field holds its zero value: empty string, 0, nil-time, empty slice/map, or whitespace-only string. E.g. a SysUser with empty NickName passed to TestVerify/TestVerifyIdWithNamedAssociation-style Verify calls.

Common situations: A form/API request omitted the field but the handler still runs Verify; JSON binding left the field at its zero value because the client sent "" or omitted the key; a default value was never applied before validation; white-space input passed frontend checks but fails isBlank on the server.

Related errors


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