{"record":{"id":"d5e944e84a2a5882","repo":"cilium/cilium","slug":"expected-non-zero-array-length","errorCode":null,"errorMessage":"expected non-zero array length","messagePattern":"expected non-zero array length","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"tools/metricslint/pkg/analyzer/analyzer.go","lineNumber":87,"sourceCode":"\tif len(call.Args) != 1 {\n\t\treturn 0, fmt.Errorf(\"unsupported ellipsis expression\")\n\t}\n\tif warnDeprecated {\n\t\tfmt.Fprintf(os.Stderr, \"metricslint: Warning: Using deprecated 'ast.Object'\\n\")\n\t\twarnDeprecated = false\n\t}\n\n\tslice, err := getEllipsisRHSExpansion(call.Args[0])\n\tif slice == nil {\n\t\treturn 0, fmt.Errorf(\"unsupported varlen array: %w\", err)\n\t}\n\tif _, ok := slice.Type.(*ast.ArrayType); ok {\n\t\t// Ellipsis points to a static array, so we can count the\n\t\t// number of parameters to the method following expansion.\n\t\treturn len(slice.Elts), nil\n\t}\n\tif len(slice.Elts) != 1 {\n\t\terr := fmt.Errorf(\"expected non-zero array length\")\n\t\treturn 0, fmt.Errorf(\"unsupported nested varlen array: %w\", err)\n\t}\n\n\tnestedKV, ok := slice.Elts[0].(*ast.KeyValueExpr)\n\tif !ok {\n\t\treturn 0, fmt.Errorf(\"unsupported nested varlen array type\")\n\t}\n\tnestedSlice, err := getEllipsisRHSExpansion(nestedKV.Value)\n\tif nestedSlice == nil {\n\t\treturn 0, fmt.Errorf(\"unsupported nested varlen array: %w\", err)\n\t}\n\treturn len(nestedSlice.Elts), nil\n}\n\nfunc filterRelevantConstructors(node ast.Node) (object, constructor string, argCount int, err error) {\n\t// Look for an initializer with key-value expressions that call another\n\t// function to initialize the field.\n\tkv, ok := node.(*ast.KeyValueExpr)","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/tools/metricslint/pkg/analyzer/analyzer.go#L69-L105","documentation":"When the spread slice's type is not an *ast.ArrayType (so it's not a simple static array), the analyzer expects the literal to contain exactly one KeyValueExpr element describing a nested map/slice initializer. If the composite literal has zero or multiple elements, this inner 'expected non-zero array length' error is created and wrapped as 'unsupported nested varlen array'.","triggerScenarios":"Spread argument is a composite literal whose Type is not a plain ArrayType and whose Elts length != 1, e.g. an empty literal []string{} or a literal with two+ non-keyed elements reaching the nested-expansion branch.","commonSituations":"Empty label slices passed with '...' in one branch of the code; map-typed literals (map[string][]string{...}) with several entries; hand-written nested initializers the analyzer didn't anticipate.","solutions":["Ensure the literal has exactly one element in the nested form the analyzer expects: `m := map[string][]string{\"k\": {\"a\", \"b\"}}`.","For static arrays, declare with an explicit ArrayType so the earlier `len(slice.Elts)` path is used instead.","Avoid passing empty literals with '...'; provide at least one element or restructure.","Suppress the analyzer report if the code is valid; this is a tool limitation.","Extend countArgs to handle multi-element non-array literals via go/types."],"exampleFix":"// before\n// labels := map[string][]string{}\n// counter.WithLabels(labels[\"k\"]...)\n// after\n// labels := map[string][]string{\"k\": {\"src\", \"dst\"}}\n// counter.WithLabels(labels[\"k\"]...)","handlingStrategy":"validation","validationCode":"// For nested (non-array) literals, keep exactly one KeyValueExpr element:\n// m := map[string][]string{\"k\": {\"a\", \"b\"}}\n// counter.WithLabels(m[\"k\"]...)\nfunc singleKVLiteral(lit *ast.CompositeLit) bool {\n    if _, isArray := lit.Type.(*ast.ArrayType); isArray {\n        return true\n    }\n    return len(lit.Elts) == 1\n}","typeGuard":"func nestedShapeSupported(lit *ast.CompositeLit) bool {\n    if _, ok := lit.Type.(*ast.ArrayType); ok {\n        return true\n    }\n    if len(lit.Elts) != 1 {\n        return false\n    }\n    _, ok := lit.Elts[0].(*ast.KeyValueExpr)\n    return ok\n}","tryCatchPattern":"if len(slice.Elts) != 1 {\n    log.Printf(\"literal has %d elements; analyzer only supports 1 nested entry\", len(slice.Elts))\n    return\n}","preventionTips":["Avoid empty literals in the spread position of metric calls.","Use one-entry map/nested literals when relying on nested expansion.","Prefer explicit ArrayType literals so the static-array path is used.","Suppress reports for legitimately empty label sets."],"tags":["go","static-analysis","ast","linter"],"backgroundTag":"analyzer-ast-parse-limitation","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}