larksuite/cli · error

nil-capable encoding=json input must declare nullable or non

Error message

nil-capable encoding=json input must declare nullable or nonnullable

What it means

For encoding=json fields whose Go type can hold nil (slices, maps, pointers, interfaces), the author must state explicitly via `nullable` or `nonnullable` in the schema tag whether a null JSON value is allowed. The omission check is skipped when the shape was declared explicitly (shapeExplicit or an explicitly nullable shape), but a bare nil-capable type with no declaration fails validation.

Source

Thrown at shortcuts/common/typed_compile_args.go:336

			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)
		}
		if alias.Name == field.name {
			return fmt.Errorf("alias[%d] duplicates canonical flag --%s", i, field.name)
		}
		if _, duplicate := seenAliases[alias.Name]; duplicate {
			return fmt.Errorf("duplicate alias --%s", alias.Name)
		}
		seenAliases[alias.Name] = struct{}{}
		switch alias.Mode {
		case typedAliasNormalize:

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Add `nullable` (accept explicit null) or `nonnullable` (reject null) to the schema tag.
  2. Or declare an explicit Shape that already states nullability, satisfying shapeExplicit.
  3. Make the type non-nil-capable (e.g. struct instead of map/slice) if null never applies.

Example fix

// before
Filter map[string]string `schema:"optional" cli:"encoding=json"`
// after
Filter map[string]string `schema:"optional;nonnullable" cli:"encoding=json"`
Defensive patterns

Strategy: validation

Validate before calling

func jsonFieldDeclaresNullability(schemaTagStr string) error {
	if strings.Contains(schemaTagStr, "nullable") || strings.Contains(schemaTagStr, "nonnullable") {
		return nil
	}
	return fmt.Errorf("encoding=json nil-capable fields must declare nullable or nonnullable")
}

Prevention

When it happens

Trigger: A field like []string or map[string]string with cli:"encoding=json" whose schema tag has neither `nullable` nor `nonnullable`, and no explicit Shape covering nullability; compileInput -> validateInputCLI fails.

Common situations: Adding encoding=json to an existing optional field without revisiting its schema tag; upgrading the typed-input framework where the explicit-nullability declaration became mandatory.

Related errors


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