larksuite/cli · error

description is declared by both doc and InputField.Descripti

Error message

description is declared by both doc and InputField.Description

What it means

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.

Source

Thrown at shortcuts/common/typed_compile_args.go:206

	publicProvided := t.PkgPath() == extensionCommandPkgPath && strings.HasPrefix(t.Name(), "Provided[")
	if t.Kind() != reflect.Struct || !publicProvided {
		return t, nil, false, nil
	}
	value, ok := t.FieldByName("Value")
	if !ok {
		return nil, nil, false, fmt.Errorf("Provided type has no Value field")
	}
	set, ok := t.FieldByName("Set")
	if !ok || set.Type.Kind() != reflect.Bool {
		return nil, nil, false, fmt.Errorf("Provided type has invalid Set field")
	}
	return value.Type, value.Index, true, nil
}

func mergeInputSupplement(field *compiledInputField, supplement typedInputField) error {
	if supplement.Description != "" {
		if field.description != "" {
			return fmt.Errorf("description is declared by both doc and InputField.Description")
		}
		field.description = strings.TrimSpace(supplement.Description)
	}
	if supplement.Shape != nil {
		if shapeHasConstraints(field.shape) || field.nullable != nil {
			return fmt.Errorf("Shape conflicts with schema constraints or nullable declaration")
		}
		shape, err := lowerAuthoringShape(supplement.Shape)
		if err != nil {
			return err
		}
		if err := validateShape(shape, "InputField.Shape"); err != nil {
			return err
		}
		if !shapeCompatibleWithType(shape, field.valueType) {
			return fmt.Errorf("InputField.Shape %T is incompatible with Go type %s", supplement.Shape, field.valueType)
		}
		field.shape = shape

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Remove either the doc tag or the InputField.Description so only one remains.
  2. Prefer the doc tag for simple inline descriptions; use InputField.Description only when the tag is absent.

Example fix

// before
Query string `flag:"query" schema:"required" doc:"Search query"`
// plus InputField{Name:"query", Description:"Search query"}
// after
Query string `flag:"query" schema:"required" doc:"Search query"`
// and remove Description from the InputField
Defensive patterns

Strategy: validation

Validate before calling

if field.Tag.Get("doc") != "" {
	for _, f := range input.Fields {
		if f.Name == flagName && f.Description != "" {
			return fmt.Errorf("flag %s has both doc tag and InputField.Description", flagName)
		}
	}
}

Prevention

When it happens

Trigger: Args field with `doc:"Search query"` plus registration code Input.Fields entry {Name:"query", Description:"Search query"} for the same flag.

Common situations: Adding InputField metadata to an existing tagged field without removing the doc tag; copy-pasting Input.Fields blocks onto already-documented Args structs.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/f732de725916bf97. Report an issue: GitHub.