kubernetes/kops · error
BuildFlags of value type not handled: %T %s=%v
Error message
BuildFlags of value type not handled: %T %s=%v
What it means
The flag builder only knows how to render maps of type map[string]string. When reflection reaches a field with a `flag` tag whose underlying value is a Map of any other key/value type, it cannot serialize it and returns this error. It guards against silently emitting malformed flags.
Source
Thrown at pkg/flagbuilder/build_flags.go:119
return nil
}
// We handle a map[string]string like --node-labels=k1=v1,k2=v2 etc
// As we need more formats we can add additional spec to the flags tag
if stringStringMap, ok := val.Interface().(map[string]string); ok {
var args []string
for k, v := range stringStringMap {
arg := fmt.Sprintf("%s=%s", k, v)
args = append(args, arg)
}
sort.Strings(args)
if len(args) != 0 {
flag := fmt.Sprintf("--%s=%s", flagName, strings.Join(args, ","))
flags = append(flags, flag)
}
return reflectutils.SkipReflection
}
return fmt.Errorf("BuildFlags of value type not handled: %T %s=%v", val.Interface(), path, val.Interface())
}
if val.Kind() == reflect.Slice {
if val.IsNil() {
return nil
}
// We handle a []string like --admission-control=v1,v2 etc
if stringSlice, ok := val.Interface().([]string); ok {
if len(stringSlice) != 0 {
if repeatFlag {
for _, v := range stringSlice {
flag := fmt.Sprintf("--%s=%s", flagName, v)
flags = append(flags, flag)
}
} else {
flag := fmt.Sprintf("--%s=%s", flagName, strings.Join(stringSlice, ","))
flags = append(flags, flag)
}View on GitHub (pinned to 4c8573c808)
Solutions
- Change the field type to map[string]string, converting values to strings when populating it
- Remove the `flag` tag from the field if it should not be rendered as a flag
- Add a custom branch in the walker for the specific map type if string conversion is safe
Example fix
// before Taints map[string]int `flag:"taints"` // after Taints map[string]string `flag:"taints"`
Defensive patterns
Strategy: validation
Validate before calling
// Ensure flag-tagged map fields are map[string]string before calling BuildFlagsList
if m, ok := opts.SomeMap.(map[string]string); !ok {
return fmt.Errorf("SomeMap must be map[string]string, got %T", opts.SomeMap)
} Type guard
func isStringStringMap(v reflect.Value) bool {
return v.Kind() != reflect.Map || v.Type() == reflect.TypeOf(map[string]string{})
} Try / catch
flags, err := flagbuilder.BuildFlagsList(opts)
if err != nil {
if strings.Contains(err.Error(), "value type not handled") {
log.Fatalf("config field has unsupported type for flag rendering: %v", err)
}
return err
} Prevention
- Use map[string]string exclusively for flag-tagged maps
- Convert typed values to strings when populating flaggable config structs
- Add BuildFlagsList smoke tests covering all option structs in CI
When it happens
Trigger: A field with a `flag` tag is a map[string]int, map[string]bool, map[string][]string, or any non-string-typed map (after pointer dereference), and BuildFlags/BuildFlagsList is called on the options struct.
Common situations: Introducing a new config field with a typed map and forgetting to convert it to map[string]string, or embedding third-party types (e.g. resource maps) into a flaggable struct.
Related errors
- BuildFlagsList of value type not handled: %T %s=%v
- cannot parse flag spec: %q
- BuildFlagsList to reflect value: %s
- unhandled type %v %q
- unhandled type %q
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/c78e46107385c6df.
Report an issue: GitHub.