{"record":{"id":"a509bb5633e1fa74","repo":"larksuite/cli","slug":"nullable-requires-a-nil-capable-go-type","errorCode":null,"errorMessage":"nullable requires a nil-capable Go type","messagePattern":"nullable requires a nil-capable Go type","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/common/typed_compile_args.go","lineNumber":501,"sourceCode":"\t\t\tresult.minItems = &v\n\t\tcase \"maxItems\":\n\t\t\tv, err := parseNonnegativeInt(value)\n\t\t\tif err != nil {\n\t\t\t\treturn result, fmt.Errorf(\"schema maxItems: %w\", err)\n\t\t\t}\n\t\t\tresult.maxItems = &v\n\t\tdefault:\n\t\t\treturn result, fmt.Errorf(\"unknown schema token %q\", key)\n\t\t}\n\t}\n\tif result.required == result.optional {\n\t\treturn result, fmt.Errorf(\"schema must declare exactly one of required or optional\")\n\t}\n\tif result.required && result.defaultValue.Set {\n\t\treturn result, fmt.Errorf(\"required input cannot declare default\")\n\t}\n\tif result.nullable != nil && *result.nullable && !isNilCapable(valueType) {\n\t\treturn result, fmt.Errorf(\"nullable requires a nil-capable Go type\")\n\t}\n\tif result.minLength != nil && result.maxLength != nil && *result.minLength > *result.maxLength {\n\t\treturn result, fmt.Errorf(\"minLength exceeds maxLength\")\n\t}\n\tif result.minimum != nil && result.maximum != nil && *result.minimum > *result.maximum {\n\t\treturn result, fmt.Errorf(\"minimum exceeds maximum\")\n\t}\n\tif result.minItems != nil && result.maxItems != nil && *result.minItems > *result.maxItems {\n\t\treturn result, fmt.Errorf(\"minItems exceeds maxItems\")\n\t}\n\treturn result, nil\n}\n\nfunc parseCLITag(raw string) (typedCLIInput, error) {\n\tvar result typedCLIInput\n\tif raw == \"\" {\n\t\treturn result, nil\n\t}","sourceCodeStart":483,"sourceCodeEnd":519,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/common/typed_compile_args.go#L483-L519","documentation":"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.","triggerScenarios":"A tag such as schema:\"optional;nullable\" on a field of type string, int, bool, or another non-nil-capable value type.","commonSituations":"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.","solutions":["Change the field type to a pointer or other nil-capable type, e.g. *string.","If absence is the real goal, rely on `optional` alone and drop nullable.","Use nonnullable explicitly if the field must never be null."],"exampleFix":"// before\nName string `schema:\"optional;nullable\"`\n// after\nName *string `schema:\"optional;nullable\"`","handlingStrategy":"type-guard","validationCode":"func nilCapable(t reflect.Type) bool {\n\tswitch t.Kind() {\n\tcase reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Pointer, reflect.Slice, reflect.UnsafePointer:\n\t\treturn true\n\t}\n\treturn false\n}","typeGuard":"func isNilCapableType[T any]() bool {\n\tvar zero T\n\tt := reflect.TypeOf(&zero).Elem()\n\tswitch t.Kind() {\n\tcase reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Pointer, reflect.Slice:\n\t\treturn true\n\t}\n\treturn false\n}","tryCatchPattern":null,"preventionTips":["Only mark pointer/slice/map/interface fields as nullable.","For value types, use `optional` alone to express absence.","Prefer *string/*int64 explicitly when an explicit null must round-trip to the API."],"tags":["go","struct-tags","type-system","schema-validation"],"backgroundTag":"nullable-requires-pointer-type","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"}