{"record":{"id":"3f033ffaccdca7a4","repo":"kubernetes/kops","slug":"buildflagslist-of-value-type-not-handled-t-s-v","errorCode":null,"errorMessage":"BuildFlagsList of value type not handled: %T %s=%v","messagePattern":"BuildFlagsList of value type not handled: %T (.+?)=(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/flagbuilder/build_flags.go","lineNumber":203,"sourceCode":"\t\t\t// Go renders a time.Duration to `0` in <= 1.6, and `0s` in >= 1.7\n\t\t\t// We force it to be `0s`, regardless of value\n\t\t\tif vString == \"0\" {\n\t\t\t\tvString = \"0s\"\n\t\t\t}\n\n\t\t\tif vString != flagEmpty {\n\t\t\t\tflag = fmt.Sprintf(\"--%s=%s\", flagName, vString)\n\t\t\t}\n\n\t\tcase resource.Quantity:\n\t\t\t// Format as a floating point value (i.e. 3.14, not 3140m)\n\t\t\tvString := v.AsDec().String()\n\t\t\tif vString != flagEmpty {\n\t\t\t\tflag = fmt.Sprintf(\"--%s=%s\", flagName, vString)\n\t\t\t}\n\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"BuildFlagsList of value type not handled: %T %s=%v\", v, path, v)\n\t\t}\n\t\tif flag != \"\" {\n\t\t\tflags = append(flags, flag)\n\t\t}\n\n\t\treturn reflectutils.SkipReflection\n\t}\n\terr := reflectutils.ReflectRecursive(reflect.ValueOf(options), walker, &reflectutils.ReflectOptions{DeprecatedDoubleVisit: true})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"BuildFlagsList to reflect value: %s\", err)\n\t}\n\t// Sort so that the order is stable across runs\n\tsort.Strings(flags)\n\n\treturn flags, nil\n}\n\n// maybeQuote quotes s when it contains a double quote, so values survive the space-separated","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/flagbuilder/build_flags.go#L185-L221","documentation":"After maps and slices, the walker switches on scalar/value kinds it can render: string, *string, bool, ints, floats, metav1.Duration and resource.Quantity. A field with a `flag` tag of any other type (e.g. time.Time, custom struct, map-like value type) hits the default case and returns this error.","triggerScenarios":"A field with a `flag` tag has a scalar type outside the supported switch, such as time.Time, time.Duration (bare, not metav1.Duration), int8/uint, or a nested struct value reached at leaf position.","commonSituations":"Using stdlib time.Duration instead of metav1.Duration in a flaggable config struct, adding a new typed field and forgetting the flag tag, or nesting structs that end up as leaves with a `flag` tag.","solutions":["Change the field to one of the supported types (string, *string, bool, int/int32/int64, float32/float64, metav1.Duration, resource.Quantity)","Remove the `flag` tag so the field is skipped or descended instead of rendered","Extend the switch at build_flags.go:146-203 to handle the new type"],"exampleFix":"// before\nIdleTimeout time.Duration `flag:\"idle-timeout\"`\n// after\nIdleTimeout metav1.Duration `flag:\"idle-timeout\"`","handlingStrategy":"validation","validationCode":"// Check flag-tagged leaf fields use a supported type before building flags\nsupported := map[reflect.Type]bool{\n\treflect.TypeOf(\"\"): true,\n\treflect.TypeOf((*string)(nil)): true,\n\treflect.TypeOf(false): true,\n\treflect.TypeOf(int32(0)): true,\n\treflect.TypeOf(int64(0)): true,\n\treflect.TypeOf(metav1.Duration{}): true,\n\treflect.TypeOf(resource.Quantity{}): true,\n}\nv := reflect.ValueOf(opts).FieldByName(\"IdleTimeout\")\nif !supported[v.Type()] {\n\treturn fmt.Errorf(\"field type %s not supported by flagbuilder\", v.Type())\n}","typeGuard":"func isFlaggableScalar(v reflect.Value) bool {\n\tswitch v.Interface().(type) {\n\tcase string, *string, bool, int, int32, int64, float32, float64, metav1.Duration, resource.Quantity:\n\t\treturn true\n\t}\n\treturn false\n}","tryCatchPattern":"flags, err := flagbuilder.BuildFlagsList(opts)\nif err != nil {\n\tif strings.Contains(err.Error(), \"BuildFlagsList of value type not handled\") {\n\t\tlog.Fatalf(\"flag-tagged field has unsupported type: %v\", err)\n\t}\n\treturn err\n}","preventionTips":["Use metav1.Duration, not time.Duration, in flaggable structs","Keep the flagbuilder type switch in mind when adding new config fields","Cover all option structs with BuildFlagsList tests"],"tags":["reflection","flagbuilder","unsupported-type"],"backgroundTag":"unsupported-flag-value-type","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}