larksuite/cli · error

encoding comma_or_repeated only supports string or integer…

Error message

encoding comma_or_repeated only supports string or integer arrays

What it means

encoding=comma_or_repeated splits CLI input into list elements, so the slice element must be parseable from a plain token. Only string and integer element kinds are supported; other element types (bool, float, structs, pointers to them, etc.) are rejected at compile time of the input struct.

Solutions

  1. Change the element type to string or an integer kind (int, int8..int64, uint variants).
  2. Use encoding=json instead, which accepts arbitrary element types via a JSON array value.
  3. Parse exotic element types manually in the shortcut rather than via typed CLI encoding.

Example fix

// before
Ratios []float64 `schema:"optional" cli:"encoding=comma_or_repeated"`
// after
Ratios []int `schema:"optional" cli:"encoding=comma_or_repeated"`
Defensive patterns

Strategy: validation

Validate before calling

func validCommaOrRepeatedElem(v any) error {
	t := reflect.TypeOf(v)
	for t != nil && t.Kind() == reflect.Ptr { t = t.Elem() }
	if t == nil || (t.Kind() != reflect.Slice && t.Kind() != reflect.Array) {
		return fmt.Errorf("needs slice/array")
	}
	k := t.Elem().Kind()
	intKinds := map[reflect.Kind]bool{reflect.Int: true, reflect.Int8: true, reflect.Int16: true, reflect.Int32: true, reflect.Int64: true, reflect.Uint: true, reflect.Uint8: true, reflect.Uint16: true, reflect.Uint32: true, reflect.Uint64: true}
	if k != reflect.String && !intKinds[k] {
		return fmt.Errorf("comma_or_repeated element must be string or integer, got %v", k)
	}
	return nil
}

Type guard

func isStringOrIntSlice(t reflect.Type) bool {
	for t != nil && t.Kind() == reflect.Ptr { t = t.Elem() }
	if t == nil || (t.Kind() != reflect.Slice && t.Kind() != reflect.Array) { return false }
	k := t.Elem().Kind()
	return k == reflect.String || strings.HasPrefix(k.String(), "int") || strings.HasPrefix(k.String(), "uint")
}

Prevention

When it happens

Trigger: A field like `[]bool`, `[]float64`, `[]time.Duration`, or `[]*string` declares cli:"encoding=comma_or_repeated"; validateInputCLI inspects indirectType(field.valueType).Elem().Kind() and it is neither reflect.String nor an integer kind.

Common situations: Assuming any slice type works with comma_or_repeated because []string and []int do; switching []int to []float64; using a slice of custom string-like types without a supported underlying kind.

Related errors


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

Appendix: source

Thrown at shortcuts/common/typed_compile_args.go:326

			return fmt.Errorf("complex input requires encoding")
		}
	case typedEncodingRepeated:
		if kind != reflect.Slice && kind != reflect.Array {
			return fmt.Errorf("encoding repeated requires an array or slice")
		}
		if indirectType(field.valueType).Elem().Kind() != reflect.String {
			return fmt.Errorf("encoding repeated only supports string arrays")
		}
		if field.nullable != nil {
			return fmt.Errorf("encoding repeated does not allow nullable/nonnullable")
		}
	case typedEncodingCommaOrRepeated:
		if kind != reflect.Slice && kind != reflect.Array {
			return fmt.Errorf("encoding comma_or_repeated requires an array or slice")
		}
		elementKind := indirectType(field.valueType).Elem().Kind()
		if elementKind != reflect.String && !isIntegerKind(elementKind) {
			return fmt.Errorf("encoding comma_or_repeated only supports string or integer arrays")
		}
		if field.nullable != nil {
			return fmt.Errorf("encoding comma_or_repeated does not allow nullable/nonnullable")
		}
	case typedEncodingJSON:
		if kind != reflect.Slice && kind != reflect.Array && kind != reflect.Struct && kind != reflect.Map && kind != reflect.Interface {
			return fmt.Errorf("encoding json requires array, object, oneOf, or custom JSON input")
		}
		if isNilCapable(field.valueType) && field.nullable == nil && !field.shapeExplicit && !shapeExplicitlyNullable(field.shape) {
			return fmt.Errorf("nil-capable encoding=json input must declare nullable or nonnullable")
		}
	default:
		return fmt.Errorf("unknown CLI encoding %q", field.cli.Encoding)
	}
	seenAliases := make(map[string]struct{})
	for i, alias := range field.cli.Aliases {
		if !aliasNamePattern.MatchString(alias.Name) {
			return fmt.Errorf("alias[%d] name %q is invalid", i, alias.Name)

View on GitHub (pinned to 7fd6ef3c07)