kubernetes/kops · error
cannot set value
Error message
cannot set value
What it means
setType is the low-level setter used by SetString; it refuses to write when v.CanSet() is false, meaning the reflect.Value is not addressable. This guards against mutating unexported fields or values obtained from non-pointer targets.
Source
Thrown at util/pkg/reflectutils/access.go:116
return nil
}
err = ReflectRecursive(targetValue, visitor, &ReflectOptions{JSONNames: true})
if err != nil {
return err
}
if !fieldSet {
return fmt.Errorf("field %s not found in %s", targetPath, BuildTypeName(reflect.TypeOf(target)))
}
return nil
}
func setType(v reflect.Value, newValue string) error {
if !v.CanSet() {
return fmt.Errorf("cannot set value")
}
if v.Type().Kind() == reflect.Slice {
// To support multiple values, we split on commas.
// We have no way to escape a comma currently; but in general we prefer having a slice in the schema,
// rather than having values that need to be parsed, so we may not need it.
tokens := strings.Split(newValue, ",")
valueArray := reflect.MakeSlice(v.Type(), 0, v.Len()+len(tokens))
valueArray = reflect.AppendSlice(valueArray, v)
for _, s := range tokens {
valueItem := reflect.New(v.Type().Elem())
if err := setType(valueItem.Elem(), s); err != nil {
return err
}
valueArray = reflect.Append(valueArray, valueItem.Elem())
}
reflect.New(v.Type().Elem())
v.Set(valueArray)View on GitHub (pinned to 4c8573c808)
Solutions
- Pass a pointer to the top-level struct to SetString.
- Make the target field exported in the struct definition.
- Copy the object to a locally addressable variable (&obj) before mutating.
Example fix
// before reflectutils.SetString(cfg, "spec.field", "x") // cfg is a struct value // after reflectutils.SetString(&cfg, "spec.field", "x")
Defensive patterns
Strategy: validation
Validate before calling
v := reflect.ValueOf(target)
if v.Kind() != reflect.Ptr || v.IsNil() {
return errors.New("target must be an addressable pointer")
} Type guard
func isAddressable(target interface{}) bool {
v := reflect.ValueOf(target)
return v.Kind() == reflect.Ptr && v.Elem().CanSet()
} Try / catch
if err := SetString(&obj, path, val); err != nil {
if err.Error() == "cannot set value" || strings.Contains(err.Error(), "cannot set value") {
return fmt.Errorf("field %q is not settable (unexported or non-addressable)", path)
}
return err
} Prevention
- Pass pointers, not values, to SetString.
- Avoid unexported fields on paths you intend to mutate.
- Do not target fields inside map values.
When it happens
Trigger: SetString reaching the matched leaf through an unexported field, or being handed a non-addressable value (struct passed by value, map value, interface holding a copy).
Common situations: Calling SetString(&structByValue,...) where an intermediate field is unexported; using SetString on values pulled from maps or slices of non-pointer elements.
Related errors
- conversion error for field %s: %s
- unable to convert from Quantity %v to float
- BuildFlagsList to reflect value: %s
- only accepts structs; got %T
- unhandled type %v %q
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/7f32732fbef2b9e9.
Report an issue: GitHub.