{"record":{"id":"f732de725916bf97","repo":"larksuite/cli","slug":"description-is-declared-by-both-doc-and-inputfield","errorCode":null,"errorMessage":"description is declared by both doc and InputField.Description","messagePattern":"description is declared by both doc and InputField\\.Description","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/common/typed_compile_args.go","lineNumber":206,"sourceCode":"\tpublicProvided := t.PkgPath() == extensionCommandPkgPath && strings.HasPrefix(t.Name(), \"Provided[\")\n\tif t.Kind() != reflect.Struct || !publicProvided {\n\t\treturn t, nil, false, nil\n\t}\n\tvalue, ok := t.FieldByName(\"Value\")\n\tif !ok {\n\t\treturn nil, nil, false, fmt.Errorf(\"Provided type has no Value field\")\n\t}\n\tset, ok := t.FieldByName(\"Set\")\n\tif !ok || set.Type.Kind() != reflect.Bool {\n\t\treturn nil, nil, false, fmt.Errorf(\"Provided type has invalid Set field\")\n\t}\n\treturn value.Type, value.Index, true, nil\n}\n\nfunc mergeInputSupplement(field *compiledInputField, supplement typedInputField) error {\n\tif supplement.Description != \"\" {\n\t\tif field.description != \"\" {\n\t\t\treturn fmt.Errorf(\"description is declared by both doc and InputField.Description\")\n\t\t}\n\t\tfield.description = strings.TrimSpace(supplement.Description)\n\t}\n\tif supplement.Shape != nil {\n\t\tif shapeHasConstraints(field.shape) || field.nullable != nil {\n\t\t\treturn fmt.Errorf(\"Shape conflicts with schema constraints or nullable declaration\")\n\t\t}\n\t\tshape, err := lowerAuthoringShape(supplement.Shape)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := validateShape(shape, \"InputField.Shape\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif !shapeCompatibleWithType(shape, field.valueType) {\n\t\t\treturn fmt.Errorf(\"InputField.Shape %T is incompatible with Go type %s\", supplement.Shape, field.valueType)\n\t\t}\n\t\tfield.shape = shape","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/common/typed_compile_args.go#L188-L224","documentation":"A flag's description may come from exactly one source: the struct `doc` tag or InputField.Description in the programmatic field declaration. Supplying both is ambiguous and rejected during mergeInputSupplement at command registration/startup.","triggerScenarios":"Args field with `doc:\"Search query\"` plus registration code Input.Fields entry {Name:\"query\", Description:\"Search query\"} for the same flag.","commonSituations":"Adding InputField metadata to an existing tagged field without removing the doc tag; copy-pasting Input.Fields blocks onto already-documented Args structs.","solutions":["Remove either the doc tag or the InputField.Description so only one remains.","Prefer the doc tag for simple inline descriptions; use InputField.Description only when the tag is absent."],"exampleFix":"// before\nQuery string `flag:\"query\" schema:\"required\" doc:\"Search query\"`\n// plus InputField{Name:\"query\", Description:\"Search query\"}\n// after\nQuery string `flag:\"query\" schema:\"required\" doc:\"Search query\"`\n// and remove Description from the InputField","handlingStrategy":"validation","validationCode":"if field.Tag.Get(\"doc\") != \"\" {\n\tfor _, f := range input.Fields {\n\t\tif f.Name == flagName && f.Description != \"\" {\n\t\t\treturn fmt.Errorf(\"flag %s has both doc tag and InputField.Description\", flagName)\n\t\t}\n\t}\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Document each flag in exactly one place: doc tag or InputField.Description.","When adding InputField metadata to an existing field, check for an existing doc tag first.","Grep Args structs for doc tags before adding Input.Fields entries."],"tags":["cli","documentation","conflict","validation"],"backgroundTag":"duplicate-declaration-conflict","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"}