{"record":{"id":"b5ba313bb0f9ec85","repo":"larksuite/cli","slug":"s-is-nil","errorCode":null,"errorMessage":"%s is nil","messagePattern":"(.+?) is nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/common/typed_compile_data.go","lineNumber":258,"sourceCode":"\t\tif isNilCapable(field.Type) && schema.nullable == nil {\n\t\t\treturn typedObjectShape{}, fmt.Errorf(\"%s field %s (%s): nil-capable field must declare nullable or nonnullable\", path, field.Name, name)\n\t\t}\n\t\tdescription := strings.TrimSpace(field.Tag.Get(\"doc\"))\n\t\tif input && description == \"\" {\n\t\t\treturn typedObjectShape{}, fmt.Errorf(\"%s field %s (%s): description is required via doc\", path, field.Name, name)\n\t\t}\n\t\tfieldShape, err := shapeForType(field.Type, schema, input, active)\n\t\tif err != nil {\n\t\t\treturn typedObjectShape{}, fmt.Errorf(\"%s field %s (%s): %w\", path, field.Name, name, err)\n\t\t}\n\t\tshape.Fields = append(shape.Fields, typedValueField{Name: name, Description: description, Required: schema.required, Shape: fieldShape})\n\t}\n\treturn shape, nil\n}\n\nfunc validateShape(shape typedValueShape, path string) error {\n\tif shape == nil {\n\t\treturn fmt.Errorf(\"%s is nil\", path)\n\t}\n\tswitch value := shape.(type) {\n\tcase anyJSONShape:\n\tcase typedStringShape:\n\t\tif value.MinLength != nil && *value.MinLength < 0 || value.MaxLength != nil && *value.MaxLength < 0 {\n\t\t\treturn fmt.Errorf(\"%s string lengths must be nonnegative\", path)\n\t\t}\n\t\tif value.MinLength != nil && value.MaxLength != nil && *value.MinLength > *value.MaxLength {\n\t\t\treturn fmt.Errorf(\"%s minLength exceeds maxLength\", path)\n\t\t}\n\tcase typedBooleanShape:\n\tcase typedIntegerShape:\n\t\tif value.Minimum != nil && value.Maximum != nil && *value.Minimum > *value.Maximum {\n\t\t\treturn fmt.Errorf(\"%s minimum exceeds maximum\", path)\n\t\t}\n\tcase typedNumberShape:\n\t\tfor _, number := range append(append([]float64{}, value.Enum...), pointerFloats(value.Minimum, value.Maximum)...) {\n\t\t\tif math.IsNaN(number) || math.IsInf(number, 0) {","sourceCodeStart":240,"sourceCodeEnd":276,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/common/typed_compile_data.go#L240-L276","documentation":"validateShape rejects a typedValueShape that is nil at the given JSON-pointer-like path. Shapes are built either by compileStructShape/lowerAuthoringShape or supplied explicitly via Output.Data.Shape; a nil shape means the compiler produced nothing or an authoring shape slot was left empty. It is a startup-time guard preventing a nil shape from reaching schema generation or request execution.","triggerScenarios":"An explicit Output.Data.Shape (or a nested Items/Variants/field slot inside it) is nil after lowering; validateShape is called recursively (e.g. on typedArrayShape.Items or a oneOf variant) and encounters a nil entry. Also reachable via mergeInputSupplement and DataField.Shape overrides.","commonSituations":"Hand-authoring an Output.Data.Shape literal and leaving an Items or variant field unset; an override replaces a field with a shape that fails to lower to nil; constructing shapes programmatically where an error path silently returns nil.","solutions":["Identify the empty slot from the path prefix in the message (e.g. Output.Data.Shape.Items).","Set the missing nested shape: every typedArrayShape must have Items, every typedOneOfShape needs non-nil variants, every object field needs a Shape.","If using an explicit Shape, prefer a struct-derived shape or a fully populated authoring shape literal.","If a custom lowering step produced nil, fix it to return a concrete shape or a descriptive error instead."],"exampleFix":"// before\nshape := typedArrayShape{} // Items left nil\n// after\nshape := typedArrayShape{Items: typedStringShape{MinLength: intPtr(1)}}","handlingStrategy":"validation","validationCode":"func hasNilShapeSlot(s typedValueShape) bool {\n    switch v := s.(type) {\n    case typedArrayShape:\n        return v.Items == nil || hasNilShapeSlot(v.Items)\n    case typedOneOfShape:\n        for _, variant := range v.Variants {\n            if variant == nil || hasNilShapeSlot(variant) { return true }\n        }\n    case typedObjectShape:\n        for _, f := range v.Fields {\n            if f.Shape == nil || hasNilShapeSlot(f.Shape) { return true }\n        }\n    }\n    return false\n}\n// call before handing the shape to the command definition\n// if hasNilShapeSlot(myShape) { return errors.New(\"shape has nil slots\") }","typeGuard":"func isShapeSet(s typedValueShape) bool { return s != nil }","tryCatchPattern":null,"preventionTips":["Always set Items on array shapes and at least two non-nil variants on oneOf shapes.","Prefer deriving shapes from Go structs via compileData instead of hand-authoring literals.","Check lowering/override helpers for paths that can silently return nil.","Add a unit test that runs validateShape over every declared command shape."],"tags":["go","schema","nil","validation","shortcuts"],"backgroundTag":"nil-schema-shape","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"}