{"record":{"id":"9d6c7c465f026c2e","repo":"kubernetes/kops","slug":"value-was-not-a-map-at-position-d-in-s","errorCode":null,"errorMessage":"value was not a map at position %d in %s","messagePattern":"value was not a map at position (.+?) in (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/model/components/kubescheduler/model.go","lineNumber":124,"sourceCode":"\t}\n\treturn configYAML, nil\n}\n\n// MapToUnstructured reflects the options interface and extracts the parameters for the config file\nfunc MapToUnstructured(options interface{}, target *unstructured.Unstructured) error {\n\tsetValue := func(targetPath string, val interface{}) error {\n\t\tfields := strings.Split(targetPath, \".\")\n\t\t// Cannot use unstructured.SetNestedField, because it fails with e.g. \"cannot deep copy int32\"\n\t\tparent := target.Object\n\t\tfor i := 0; i < len(fields)-1; i++ {\n\t\t\tv := parent[fields[i]]\n\t\t\tif v == nil {\n\t\t\t\tv = make(map[string]interface{})\n\t\t\t\tparent[fields[i]] = v\n\t\t\t}\n\t\t\tm, ok := v.(map[string]interface{})\n\t\t\tif !ok {\n\t\t\t\treturn fmt.Errorf(\"value was not a map at position %d in %s\", i, targetPath)\n\t\t\t}\n\t\t\tparent = m\n\t\t}\n\t\tparent[fields[len(fields)-1]] = val\n\t\treturn nil\n\t}\n\n\twalker := func(path *reflectutils.FieldPath, field *reflect.StructField, val reflect.Value) error {\n\t\tif field == nil {\n\t\t\tklog.V(8).Infof(\"ignoring non-field: %s\", path)\n\t\t\treturn nil\n\t\t}\n\n\t\ttag := field.Tag.Get(\"config\")\n\t\tif tag == \"\" {\n\t\t\tklog.V(4).Infof(\"not writing field with no config tag: %s\", path)\n\t\t\t// We want to descend - it could be a structure containing flags\n\t\t\treturn nil","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/model/components/kubescheduler/model.go#L106-L142","documentation":"This is a local helper (a mini SetNestedField) in kubescheduler/model.go that walks a path of fields through nested maps to set a final value. When an intermediate value along the path exists but is not map[string]interface{}, it cannot descend and returns this error with the path position and full target path for diagnosis.","triggerScenarios":"Calling the helper with a targetPath whose intermediate field holds a non-map value (string, slice, bool), e.g. setting \"a.b.c\" when a.b is a scalar. Reached from buildSchedulerConfig's mapping of kube-scheduler settings.","commonSituations":"Cluster spec fields mapped onto the scheduler config conflicting with an existing scalar value; YAML that flattens nested keys; type mismatches after unstructured conversion of a user manifest.","solutions":["Fix the source value so the intermediate path element is an object/map","Remove the conflicting field so the helper creates intermediate maps automatically","Log/inspect the object at the failing position (the error names the index and full path) and correct the manifest","If mapping from Cluster.Spec.KubeScheduler, ensure the target config has matching nested structure"],"exampleFix":"# before (config, path a.b.c)\na:\n  b: scalar\n# after\na:\n  b:\n    c: value","handlingStrategy":"type-guard","validationCode":"fields := strings.Split(targetPath, \".\")\ncur := obj\nfor i, f := range fields[:len(fields)-1] {\n    m, ok := cur[f].(map[string]interface{})\n    if !ok && cur[f] != nil {\n        return fmt.Errorf(\"path %q blocked at position %d: %q is %T\", targetPath, i, f, cur[f])\n    }\n    cur = m\n}","typeGuard":"func asMap(v interface{}) (map[string]interface{}, bool) {\n    m, ok := v.(map[string]interface{})\n    return m, ok\n}","tryCatchPattern":null,"preventionTips":["Check intermediate path values are objects before setting nested fields","Use unstructured.NestedFieldNoCopy to inspect the existing shape first","Avoid scalar values on keys used as intermediate path segments"],"tags":["unstructured","nested-map","kube-scheduler","manifest-validation"],"backgroundTag":"schema-validation-failed","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"}