{"record":{"id":"2c46b0fd01bcd7d6","repo":"larksuite/cli","slug":"output-data-overrides-require-struct-data","errorCode":null,"errorMessage":"Output.Data.Overrides require struct Data","messagePattern":"Output\\.Data\\.Overrides require struct Data","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/common/typed_compile_data.go","lineNumber":39,"sourceCode":")\n\nfunc compileData(dataType reflect.Type, definition typedDataDefinition) (typedValueShape, error) {\n\tif definition.Shape != nil && len(definition.Overrides) > 0 {\n\t\treturn nil, fmt.Errorf(\"Output.Data.Shape and Output.Data.Overrides are mutually exclusive\")\n\t}\n\tif definition.Shape != nil {\n\t\tshape, err := lowerAuthoringShape(definition.Shape)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif err := validateShape(shape, \"Output.Data.Shape\"); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn shape, nil\n\t}\n\tif dataType.Kind() == reflect.Interface && dataType.NumMethod() == 0 {\n\t\tif len(definition.Overrides) > 0 {\n\t\t\treturn nil, fmt.Errorf(\"Output.Data.Overrides require struct Data\")\n\t\t}\n\t\treturn anyJSONShape{}, nil\n\t}\n\tif dataType.Kind() != reflect.Struct {\n\t\treturn nil, fmt.Errorf(\"Data must be a non-pointer struct or any unless Output.Data.Shape is explicit, got %s\", dataType)\n\t}\n\tshape, err := compileStructShape(dataType, false, \"Data\", map[reflect.Type]struct{}{})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfor i, override := range definition.Overrides {\n\t\tif override.Path == \"\" || !strings.HasPrefix(override.Path, \"/\") {\n\t\t\treturn nil, fmt.Errorf(\"Output.Data.Overrides[%d].Path %q must be an RFC 6901 JSON Pointer\", i, override.Path)\n\t\t}\n\t\tif err := applyDataOverride(&shape, override); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"Output.Data.Overrides[%d] path %q: %w\", i, override.Path, err)\n\t\t}\n\t}","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/common/typed_compile_data.go#L21-L57","documentation":"When the Data type is the empty interface (any), compileData returns a permissive anyJSONShape, but Overrides only make sense against a concrete struct-derived shape; providing Overrides with an `any` Data type is therefore rejected because there are no fields to point into.","triggerScenarios":"Declaring Output.Data as `any` (reflect.Interface with NumMethod()==0) while also supplying Output.Data.Overrides to compileData/compileDefinitionParts.","commonSituations":"Leaving Data as `any` for dynamic payloads but still configuring legacy override paths; template code that kept `any` after adding overrides.","solutions":["Change Output.Data to a concrete non-pointer struct type whose fields the overrides target.","Remove the Overrides and keep Data as `any` for free-form JSON passthrough.","If the payload is dynamic but partially fixed, define a struct with an `any`-typed field and override into that field."],"exampleFix":"// before\nData any; Overrides: []Override{{Path:\"/name\", Value:\"x\"}}\n// after\ntype data struct { Name string `json:\"name\"` }\nData data; Overrides: []Override{{Path:\"/name\", Value:\"x\"}}","handlingStrategy":"validation","validationCode":"func overridesNeedStruct(dataType reflect.Type, n int) error {\n  if dataType.Kind() == reflect.Interface && dataType.NumMethod() == 0 && n > 0 {\n    return errors.New(\"Overrides require a struct Data type\")\n  }\n  return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never keep Data as `any` once overrides are added","Define concrete structs for any payload you intend to override","Review definitions for `any` Data during code review"],"tags":["configuration","any-type","overrides","shortcuts"],"backgroundTag":"overrides-require-struct-data","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"}