{"id":"bb3c3100602f0031","repo":"labstack/echo","slug":"query-param-form-tags-are-not-allowed-with-anonymo","errorCode":null,"errorMessage":"query/param/form tags are not allowed with anonymous struct field","messagePattern":"query/param/form tags are not allowed with anonymous struct field","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"bind.go","lineNumber":272,"sourceCode":"\t}\n\n\tmeta := bindMetaFor(typ)\n\tfor fi := range meta.fields { // iterate over all destination fields\n\t\tfm := &meta.fields[fi]\n\t\tstructField := val.Field(fm.index)\n\t\tif fm.anonymous {\n\t\t\tif structField.Kind() == reflect.Pointer {\n\t\t\t\tstructField = structField.Elem()\n\t\t\t}\n\t\t}\n\t\tif !structField.CanSet() {\n\t\t\tcontinue\n\t\t}\n\t\tstructFieldKind := structField.Kind()\n\t\tinputFieldName := fm.tagName(tag)\n\t\tif fm.anonymous && structFieldKind == reflect.Struct && inputFieldName != \"\" {\n\t\t\t// if anonymous struct with query/param/form tags, report an error\n\t\t\treturn errors.New(\"query/param/form tags are not allowed with anonymous struct field\")\n\t\t}\n\n\t\tif inputFieldName == \"\" {\n\t\t\t// If tag is nil, we inspect if the field is a not BindUnmarshaler struct and try to bind data into it (might contain fields with tags).\n\t\t\t// structs that implement BindUnmarshaler are bound only when they have explicit tag\n\t\t\tif _, ok := structField.Addr().Interface().(BindUnmarshaler); !ok && structFieldKind == reflect.Struct {\n\t\t\t\tif err := bindData(structField.Addr().Interface(), data, tag, dataFiles); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t\t// does not have explicit tag and is not an ordinary struct - so move to next field\n\t\t\tcontinue\n\t\t}\n\n\t\tif hasFiles {\n\t\t\tif ok, err := isFieldMultipartFile(structField.Type()); err != nil {\n\t\t\t\treturn err\n\t\t\t} else if ok {","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/labstack/echo/blob/05489dc1730161df26b72d1ae2a3ba6fb8178fc7/bind.go#L254-L290","documentation":"Returned by bindData when an anonymous (embedded) struct field carries an explicit param/query/form/header tag. The binder descends into anonymous struct fields to bind their inner tagged fields, but cannot resolve which inner field a tag on the outer anonymous field refers to. Echo forbids binding tags directly on embedded struct fields to avoid this ambiguity.","triggerScenarios":"Defining a struct with an embedded struct field that has a `query:\"...\"`, `param:\"...\"`, `form:\"...\"`, or `header:\"...\"` tag, then calling c.Bind / BindQueryParams / BindPathValues / BindHeaders with that struct.","commonSituations":"Embedding a shared base struct (e.g. Pagination) and accidentally adding a query/form tag to the embedding line. OpenAPI/Swagger code generators that attach tags to promoted embedded fields.","solutions":["Remove the binding tag from the anonymous/embedded field; put tags on the inner struct's own fields instead","If you need the field bound by a specific name, make it a non-anonymous (named) field and add the tag there","Implement BindUnmarshaler on the embedded type and bind it via a named field with an explicit tag"],"exampleFix":"// before\ntype Req struct {\n    Pagination `query:\"page\"`\n}\n\n// after\ntype Req struct {\n    Pagination\n}","handlingStrategy":"validation","validationCode":"// Scan struct fields at startup for tags on anonymous fields\nfunc checkNoTagsOnAnonymous(rt reflect.Type) error {\n    for i := 0; i < rt.NumField(); i++ {\n        f := rt.Field(i)\n        if f.Anonymous && hasBindTag(f.Tag) {\n            return fmt.Errorf(\"anonymous field %s must not have bind tags\", f.Name)\n        }\n    }\n    return nil\n}\nfunc hasBindTag(t reflect.StructTag) bool {\n    return t.Get(\"param\") != \"\" || t.Get(\"query\") != \"\" || t.Get(\"form\") != \"\" || t.Get(\"header\") != \"\"\n}","typeGuard":null,"tryCatchPattern":"if err := c.Bind(&req); err != nil {\n    if strings.Contains(err.Error(), \"anonymous struct field\") {\n        // fix struct definition: remove tag from embedded field\n        log.Fatal(\"remove bind tag from embedded field in \", reflect.TypeOf(req).Name())\n    }\n    return err\n}","preventionTips":["Never put param/query/form/header tags on the embedding (anonymous) line in a struct","Put binding tags on the fields inside the embedded struct instead","Code-review struct definitions that use embedded types for binding DTOs"],"tags":["binding","anonymous-struct","embedded","tags"],"analyzedSha":"05489dc1730161df26b72d1ae2a3ba6fb8178fc7","analyzedAt":"2026-08-04T21:32:47.783Z","schemaVersion":2}