{"record":{"id":"a3196bd2137fbbf4","repo":"cilium/cilium","slug":"expected-keyvalueexpr","errorCode":null,"errorMessage":"expected KeyValueExpr","messagePattern":"expected KeyValueExpr","errorType":"console","errorClass":null,"httpStatus":null,"severity":"info","filePath":"tools/metricslint/pkg/analyzer/analyzer.go","lineNumber":107,"sourceCode":"\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)\n\tif !ok {\n\t\treturn \"\", \"\", 0, fmt.Errorf(\"expected KeyValueExpr\")\n\t}\n\tkey, ok := kv.Key.(*ast.Ident)\n\tif !ok {\n\t\treturn \"\", \"\", 0, fmt.Errorf(\"expected Key as Ident\")\n\t}\n\tcall, ok := kv.Value.(*ast.CallExpr)\n\tif !ok {\n\t\treturn \"\", \"\", 0, fmt.Errorf(\"expected Value as CallExpr\")\n\t}\n\n\t// Look for a function with at least two args, where the last arg is a\n\t// composite literal (such as a slice). Example:\n\t//\n\t//     metric.NewCounterVec(opts, []string{...})\n\tif len(call.Args) < 2 {\n\t\treturn \"\", \"\", 0, fmt.Errorf(\"expected 2+ arguments to constructor\")\n\t}\n\tlastArg, ok := call.Args[len(call.Args)-1].(*ast.CompositeLit)","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/tools/metricslint/pkg/analyzer/analyzer.go#L89-L125","documentation":"filterRelevantConstructors is called for every KeyValueExpr in the AST and returns this sentinel when the node is not a *ast.KeyValueExpr. It is a benign filter signal, not a user-facing failure — the analyzer skips nodes it does not care about while hunting for *Vec constructor initializers.","triggerScenarios":"Any AST node reached by the Preorder walk that is not a key-value expression; in practice the walk is already restricted to KeyValueExpr, so this fires only for non-composite-literal key-value contexts (e.g. slice literals' elements that are not KV pairs).","commonSituations":"Code under analysis containing composite literals without keys, function calls, or other expression nodes inside literals being scanned by metricslint.","solutions":["No action needed — this error is filtered internally and the node is skipped","If it appears in a 'metricslint bug' report, inspect the flagged initializer and reshape it into a field: constructor(...) form"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"kv, ok := node.(*ast.KeyValueExpr)\nif !ok {\n    return // not an initializer; analyzer will skip\n}","tryCatchPattern":null,"preventionTips":["Initialize metrics with field: constructor(...) composite literal syntax","Understand these sentinel errors are internal filters, not code defects"],"tags":["go","static-analysis","ast","linter"],"backgroundTag":"unsupported-ast-pattern","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}