kubernetes/kops · error
found multiple Render methods that could be involved on %T
Error message
found multiple Render methods that could be involved on %T
What it means
Render uses reflection to find exactly one renderer method (Render, RenderAWS, RenderGCE, etc.) whose signature is compatible with the task and target. If two or more candidate methods match and neither is the generic Render, the dispatch is ambiguous — kops refuses to guess and returns this error naming the task type %T.
Source
Thrown at upup/pkg/fi/context.go:254
}
if typeContextPtr.ConvertibleTo(arg) {
args = append(args, reflect.ValueOf(c))
continue
}
if targetType.ConvertibleTo(arg) {
args = append(args, reflect.ValueOf(c.Target))
continue
}
match = false
break
}
if match {
if renderer.IsValid() {
if candidate.name == "Render" {
continue
}
if rendererName != "Render" {
return fmt.Errorf("found multiple Render methods that could be involved on %T", e)
}
}
rendererName = candidate.name
renderer = candidate.method
rendererArgs = args
}
}
if !renderer.IsValid() {
return fmt.Errorf("could not find Render method on type %T (target %T)", e, c.Target)
}
rendererArgs = append(rendererArgs, reflect.ValueOf(a))
rendererArgs = append(rendererArgs, reflect.ValueOf(e))
rendererArgs = append(rendererArgs, reflect.ValueOf(changes))
klog.V(11).Infof("Calling method %s on %T", rendererName, e)
rv := renderer.Call(rendererArgs)
var rvErr error
if !rv[0].IsNil() {View on GitHub (pinned to 4c8573c808)
Solutions
- Narrow the renderer method's parameter types (use the concrete aws.API/target type) so only one candidate matches.
- Implement the generic `Render(c *Context, a, e, changes Task)` method only, removing per-cloud renderers, if one implementation suffices.
- Add the specific Render<Provider> only for clouds the task truly supports and ensure other methods' first non-task parameter is not convertible from the current target.
Example fix
// before — ambiguous, both match
tfunc (t *myTask) RenderAWS(c *fi.Context, a, e, changes *myTask) error
func (t *myTask) RenderGCE(c interface{}, a, e, changes *myTask) error
// after — only the applicable provider's renderer has a matching signature
func (t *myTask) RenderAWS(c *fi.Context, a, e, changes *myTask) error
func (t *myTask) RenderGCE(g *gce.GCECloud, a, e, changes *myTask) error Defensive patterns
Strategy: validation
Validate before calling
// build-time check: exactly one renderer signature must accept the target type // keep Render<X> first param a concrete provider cloud/target type
Prevention
- Give each cloud-specific renderer a concrete provider-specific first parameter type.
- Implement only the generic Render method when one implementation suffices.
- After refactoring task method signatures, run unit tests exercising Context.Render dispatch.
When it happens
Trigger: A Task implementation defines multiple cloud-specific renderers (e.g. both RenderAWS and RenderGCE) whose parameter types are all convertible to/from the current target type, so reflection matches both; usually caused by method signatures that are too generic (accepting interfaces/targets convertible from everything).
Common situations: Custom task written by a kops contributor with overly broad Render<X> signatures (e.g. taking `interface{}` or a common Target type); refactoring that loosened a method's parameter type; adding a new RenderX without narrowing its argument types.
Related errors
- expected slice, got %T
- conversion error for field %s: %s
- unable to convert from Quantity %v to float
- BuildFlagsList to reflect value: %s
- only accepts structs; got %T
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/16c369b7c0778523.
Report an issue: GitHub.