cilium/cilium · info
expected function to be a method
Error message
expected function to be a method
What it means
filterRelevantMethods requires the receiver of a "With*" call to itself be a selector expression (a method call on some object, e.g. a.WithX() where a is itself a selector). If fn.X is not a *ast.SelectorExpr — for example a plain identifier like m.WithX() or a function literal — this error is returned. It encodes the tool's assumption that it only analyzes method chains.
Source
Thrown at tools/metricslint/pkg/analyzer/analyzer.go:160
return "", "", 0, fmt.Errorf("ignoring noisy constructor name")
}
return object, constructor, argCount, nil
}
func filterRelevantMethods(call *ast.CallExpr) (object, method string, err error) {
fn, ok := call.Fun.(*ast.SelectorExpr)
if !ok {
return "", "", fmt.Errorf("expected SelectorExpr")
}
if !strings.HasPrefix(fn.Sel.Name, "With") {
return "", "", fmt.Errorf("ignoring noisy method name")
}
obj, ok := fn.X.(*ast.SelectorExpr)
if !ok {
return "", "", fmt.Errorf("expected function to be a method")
}
return obj.Sel.Name, fn.Sel.Name, nil
}
func run(pass *analysis.Pass) (any, error) {
insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
// Collect objects that are initialized with a variable length slice
// parameter as the last argument to a constructor. Map object name to
// parameter count, and store the constructor name for later reference.
objs := make(map[string]int)
constructors := make(map[string]string)
insp.Preorder([]ast.Node{
(*ast.KeyValueExpr)(nil),
}, func(node ast.Node) {
obj, constructor, args, err := filterRelevantConstructors(node)
if err != nil {View on GitHub (pinned to ac7b90affa)
Solutions
- Verify the call site: the receiver must be a method/field access chain (obj.Method.WithX(...)).
- Ignore if the call is a direct method call on a local variable that the tool intentionally does not analyze.
- Extend the analyzer to also accept *ast.Ident receivers if that pattern should be covered.
Defensive patterns
Strategy: type-guard
Validate before calling
sel, ok := call.Fun.(*ast.SelectorExpr); if ok { _, okRecv := sel.X.(*ast.SelectorExpr); if !okRecv { /* will be skipped */ } } Type guard
func isMethodChain(call *ast.CallExpr) bool {
sel, ok := call.Fun.(*ast.SelectorExpr)
if !ok {
return false
}
_, ok = sel.X.(*ast.SelectorExpr)
return ok
} Prevention
- Call With-style builders on method chains (obj.Method.WithX) rather than bare identifiers if you want the analyzer to see them.
- Remember package-level identifiers (pkg.WithX) are not analyzed by this heuristic.
- Filter call sites with a receiver type guard before analysis.
When it happens
Trigger: A call like pkgVar.WithFoo() where pkgVar is a simple identifier (not a selector), or fn.X is any non-selector expression such as a parenthesized expression or index expression.
Common situations: Calling With-style builders on local struct variables or package-level identifiers that the analyzer's chain-heuristic does not recognize.
Related errors
- ignoring noisy method name
- unknown identifier
- expected assignment statement
- unexpected RHS expression length
- expected composite literal
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/a89fac8df673f39f.
Report an issue: GitHub.