{"record":{"id":"a14c3e4c5022d062","repo":"larksuite/cli","slug":"s-field-s-must-declare-json-tag","errorCode":null,"errorMessage":"%s field %s must declare json tag","messagePattern":"(.+?) field (.+?) must declare json tag","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/common/typed_compile_data.go","lineNumber":203,"sourceCode":"// removed once its fields are compiled, so the same type appearing twice as a\n// sibling stays legal.\nfunc compileStructShape(t reflect.Type, input bool, path string, active map[reflect.Type]struct{}) (typedObjectShape, error) {\n\tif _, cyclic := active[t]; cyclic {\n\t\treturn typedObjectShape{}, fmt.Errorf(\"recursive type %s requires an explicit Shape\", t)\n\t}\n\tactive[t] = struct{}{}\n\tdefer delete(active, t)\n\n\tshape := typedObjectShape{}\n\tseen := make(map[string]string)\n\tfor i := 0; i < t.NumField(); i++ {\n\t\tfield := t.Field(i)\n\t\tif !field.IsExported() {\n\t\t\tcontinue\n\t\t}\n\t\trawJSON, ok := field.Tag.Lookup(\"json\")\n\t\tif !ok {\n\t\t\treturn typedObjectShape{}, fmt.Errorf(\"%s field %s must declare json tag\", path, field.Name)\n\t\t}\n\t\tparts := strings.Split(rawJSON, \",\")\n\t\tname := parts[0]\n\t\tif name == \"-\" {\n\t\t\tcontinue\n\t\t}\n\t\tif name == \"\" {\n\t\t\treturn typedObjectShape{}, fmt.Errorf(\"%s field %s json tag must explicitly name the field\", path, field.Name)\n\t\t}\n\t\tomitempty := false\n\t\tfor _, option := range parts[1:] {\n\t\t\tswitch option {\n\t\t\tcase \"omitempty\":\n\t\t\t\tomitempty = true\n\t\t\tcase \"\":\n\t\t\tdefault:\n\t\t\t\treturn typedObjectShape{}, fmt.Errorf(\"%s field %s has unsupported json option %q\", path, field.Name, option)\n\t\t\t}","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/common/typed_compile_data.go#L185-L221","documentation":"This error comes from the typed shortcut data compiler when building an object shape from a struct. Every exported struct field must carry an explicit `json` tag so the compiler knows the wire name; a field without one makes the compiled schema ambiguous. The compiler refuses to guess a field name, so it fails at compile time of the type registration.","triggerScenarios":"Registering a struct with compileData/shapeForType where an exported field has no `json` tag at all, e.g. `Name string` without `json:\"name\"`.","commonSituations":"Adding a new field to an existing typed Data/Input struct and forgetting the tag; copying a struct from non-JSON code (internal models) into a typed shortcut definition; embedding types whose fields were previously serialized by other means.","solutions":["Add an explicit `json` tag to the named field, e.g. `json:\"fieldName\"`","Use `json:\"-\"` if the field is internal and should be excluded from the shape (it is then skipped)","If the field should not be part of the schema at all, make it unexported"],"exampleFix":"// before\ntype Input struct {\n    Name string\n}\n// after\ntype Input struct {\n    Name string `json:\"name\" schema:\"required\" doc:\"Display name\"`\n}","handlingStrategy":"validation","validationCode":"for i := 0; i < t.NumField(); i++ {\n    f := t.Field(i)\n    if f.IsExported() {\n        if _, ok := f.Tag.Lookup(\"json\"); !ok {\n            return fmt.Errorf(\"field %s needs a json tag\", f.Name)\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Add json tags immediately when writing any exported struct field","Add a unit test that compiles all registered typed structs early","Make linters (e.g. exhaustive/json tag linters) enforce tags in CI"],"tags":["go","struct-tags","json","schema-compile"],"backgroundTag":"missing-json-struct-tag","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}