larksuite/cli · error

nullable requires a nil-capable Go type

Error message

nullable requires a nil-capable Go type

What it means

The `nullable` schema token is only valid on Go types that can hold nil (pointers, slices, maps, interfaces, channels, funcs). Declaring nullable on a value type like string or int is impossible to honor, so parseSchemaTag rejects it at compile time.

Source

Thrown at shortcuts/common/typed_compile_args.go:501

			result.minItems = &v
		case "maxItems":
			v, err := parseNonnegativeInt(value)
			if err != nil {
				return result, fmt.Errorf("schema maxItems: %w", err)
			}
			result.maxItems = &v
		default:
			return result, fmt.Errorf("unknown schema token %q", key)
		}
	}
	if result.required == result.optional {
		return result, fmt.Errorf("schema must declare exactly one of required or optional")
	}
	if result.required && result.defaultValue.Set {
		return result, fmt.Errorf("required input cannot declare default")
	}
	if result.nullable != nil && *result.nullable && !isNilCapable(valueType) {
		return result, fmt.Errorf("nullable requires a nil-capable Go type")
	}
	if result.minLength != nil && result.maxLength != nil && *result.minLength > *result.maxLength {
		return result, fmt.Errorf("minLength exceeds maxLength")
	}
	if result.minimum != nil && result.maximum != nil && *result.minimum > *result.maximum {
		return result, fmt.Errorf("minimum exceeds maximum")
	}
	if result.minItems != nil && result.maxItems != nil && *result.minItems > *result.maxItems {
		return result, fmt.Errorf("minItems exceeds maxItems")
	}
	return result, nil
}

func parseCLITag(raw string) (typedCLIInput, error) {
	var result typedCLIInput
	if raw == "" {
		return result, nil
	}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Change the field type to a pointer or other nil-capable type, e.g. *string.
  2. If absence is the real goal, rely on `optional` alone and drop nullable.
  3. Use nonnullable explicitly if the field must never be null.

Example fix

// before
Name string `schema:"optional;nullable"`
// after
Name *string `schema:"optional;nullable"`
Defensive patterns

Strategy: type-guard

Validate before calling

func nilCapable(t reflect.Type) bool {
	switch t.Kind() {
	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Pointer, reflect.Slice, reflect.UnsafePointer:
		return true
	}
	return false
}

Type guard

func isNilCapableType[T any]() bool {
	var zero T
	t := reflect.TypeOf(&zero).Elem()
	switch t.Kind() {
	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Pointer, reflect.Slice:
		return true
	}
	return false
}

Prevention

When it happens

Trigger: A tag such as schema:"optional;nullable" on a field of type string, int, bool, or another non-nil-capable value type.

Common situations: Intending 'this input may be absent' (which is what optional means) and writing nullable instead, or converting a pointer field to a value type without removing the nullable token.

Related errors


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