Description

Undefined validation function 'required_if' on field 'Field'

https://godoc.org/github.com/go-playground/validator#hdr-Required_If

How to reproduce

package main

import (
    "github.com/gin-gonic/gin"
)

type ListReq struct {
        Id        int64  `form:"id" binding:"required,gte=1"`
    AppCode   string `form:"appCode" binding:"required"`
    BranchTag string `form:"branchTag" binding:"required_if=Id 1"`
}

func main() {
    g := gin.Default()
    g.GET("/list", func(c *gin.Context) {
        var form ListReq
            if err := c.ShouldBindQuery(&form); err != nil {
               c.String(http.StatusOK, "error")
               return
            }
                c.String(http.StatusOK, "ok")
    })
    g.Run(":9000")
}

Expectations

$ curl -i http://localhost:9000/list
ok

Actual result


$ curl -i http://localhost:9000/list
curl: (52) Empty reply from server

Undefined validation function 'required_if' on field 'BranchTag'
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/go-playground/validator/v10/cache.go:289 (0xd6ae36)
    (*Validate).parseFieldTagsRecursive: panic(strings.TrimSpace(fmt.Sprintf(undefinedValidation, current.tag, fieldName)))
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/go-playground/validator/v10/cache.go:150 (0xd68e27)
    (*Validate).extractStructCache: ctag, _ = v.parseFieldTagsRecursive(tag, fld.Name, "", false)
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/go-playground/validator/v10/validator.go:37 (0xd71aed)
    (*validate).validateStruct: cs = v.v.extractStructCache(current, typ.Name())
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/go-playground/validator/v10/validator_instance.go:304 (0xd7a02d)
    (*Validate).StructCtx: vd.validateStruct(ctx, top, val, val.Type(), vd.ns[0:0], vd.actualNs[0:0], nil)
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/go-playground/validator/v10/validator_instance.go:277 (0xd79ad6)
    (*Validate).Struct: return v.StructCtx(context.Background(), s)
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/binding/default_validator.go:30 (0xeebedd)
    (*defaultValidator).ValidateStruct: if err := v.validate.Struct(obj); err != nil {
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/binding/binding.go:115 (0xeebd29)
    validate: return Validator.ValidateStruct(obj)
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/binding/query.go:20 (0xef2ca4)
    queryBinding.Bind: return validate(obj)
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/context.go:679 (0xf00c11)
    (*Context).ShouldBindWith: return b.Bind(c.Request, obj)
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/context.go:654 (0xf00785)
    (*Context).ShouldBindQuery: return c.ShouldBindWith(obj, binding.Query)
I:/source/go/src/dev-zt-api.2345.cn/controller/webapi/appMobileController.go:186 (0x12af8c4)
    CompList: if err := c.ShouldBindQuery(&form); err != nil {
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/context.go:161 (0xefcb5b)
    (*Context).Next: c.handlers[c.index](c)
I:/source/go/src/dev-zt-api.2345.cn/middleware/user/user.go:45 (0x127f4d2)
    User.func1: c.Next()
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/context.go:161 (0xefcb5b)
    (*Context).Next: c.handlers[c.index](c)
I:/source/go/src/dev-zt-api.2345.cn/middleware/trace/traceLog.go:37 (0x12b6ae4)
    LogBase.func1: c.Next()
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/context.go:161 (0xefcb5b)
    (*Context).Next: c.handlers[c.index](c)
I:/source/go/src/dev-zt-api.2345.cn/middleware/cors/cors.go:29 (0x12b4cfa)
    Cors.func1: c.Next()
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/context.go:161 (0xefcb5b)
    (*Context).Next: c.handlers[c.index](c)
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/logger.go:241 (0xf174f7)
    LoggerWithConfig.func1: c.Next()
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/context.go:161 (0xefcb5b)
    (*Context).Next: c.handlers[c.index](c)
I:/source/go/src/dev-zt-api.2345.cn/middleware/cors/recovery.go:107 (0x12b6684)
    RecoveryWithWriter.func1: c.Next()
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/context.go:161 (0xefcb5b)
    (*Context).Next: c.handlers[c.index](c)
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/gin.go:409 (0xf09ef2)
    (*Engine).handleHTTPRequest: c.Next()
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/gin.go:367 (0xf0997e)
    (*Engine).ServeHTTP: engine.handleHTTPRequest(c)
C:/Go/src/net/http/server.go:2843 (0x9bf86a)
    serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
C:/Go/src/net/http/server.go:1925 (0x9b9944)
    (*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
C:/Go/src/runtime/asm_amd64.s:1374 (0x5f5c00)
    goexit: BYTE    $0x90   // NOP
<!-- Actual result showing the problem -->

Environment

  • go version:1.5.2
  • gin version (or commit ref):1.6.3
  • operating system:win10 1909

Comment From: Doarakko

required_if was released in v10.4.0, but because gin uses go-validator v10.2.0. https://github.com/go-playground/validator/pull/658 https://github.com/go-playground/validator/releases/tag/v10.4.0

I created a PR to upgrade go-validator! https://github.com/gin-gonic/gin/pull/2536

Comment From: gspgsp

also want to know: 2022/08/24 11:32:31 http: panic serving 192.168.0.124:58997: Undefined validation function 'excluded_if' on field 'Mobile'