kubernetes/kops · error

value was not a map at position %d in %s

Error message

value was not a map at position %d in %s

What it means

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.

Source

Thrown at pkg/model/components/kubescheduler/model.go:124

	}
	return configYAML, nil
}

// MapToUnstructured reflects the options interface and extracts the parameters for the config file
func MapToUnstructured(options interface{}, target *unstructured.Unstructured) error {
	setValue := func(targetPath string, val interface{}) error {
		fields := strings.Split(targetPath, ".")
		// Cannot use unstructured.SetNestedField, because it fails with e.g. "cannot deep copy int32"
		parent := target.Object
		for i := 0; i < len(fields)-1; i++ {
			v := parent[fields[i]]
			if v == nil {
				v = make(map[string]interface{})
				parent[fields[i]] = v
			}
			m, ok := v.(map[string]interface{})
			if !ok {
				return fmt.Errorf("value was not a map at position %d in %s", i, targetPath)
			}
			parent = m
		}
		parent[fields[len(fields)-1]] = val
		return nil
	}

	walker := func(path *reflectutils.FieldPath, field *reflect.StructField, val reflect.Value) error {
		if field == nil {
			klog.V(8).Infof("ignoring non-field: %s", path)
			return nil
		}

		tag := field.Tag.Get("config")
		if tag == "" {
			klog.V(4).Infof("not writing field with no config tag: %s", path)
			// We want to descend - it could be a structure containing flags
			return nil

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Fix the source value so the intermediate path element is an object/map
  2. Remove the conflicting field so the helper creates intermediate maps automatically
  3. Log/inspect the object at the failing position (the error names the index and full path) and correct the manifest
  4. If mapping from Cluster.Spec.KubeScheduler, ensure the target config has matching nested structure

Example fix

# before (config, path a.b.c)
a:
  b: scalar
# after
a:
  b:
    c: value
Defensive patterns

Strategy: type-guard

Validate before calling

fields := strings.Split(targetPath, ".")
cur := obj
for i, f := range fields[:len(fields)-1] {
    m, ok := cur[f].(map[string]interface{})
    if !ok && cur[f] != nil {
        return fmt.Errorf("path %q blocked at position %d: %q is %T", targetPath, i, f, cur[f])
    }
    cur = m
}

Type guard

func asMap(v interface{}) (map[string]interface{}, bool) {
    m, ok := v.(map[string]interface{})
    return m, ok
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/9d6c7c465f026c2e. Report an issue: GitHub.