abiosoft/colima · error

unexpected error nested value encoding: %w

Error message

unexpected error nested value encoding: %w

What it means

encodeYAML (util/yamlutil/yaml.go:91) applies each config value to the node tree via a Marshal/Unmarshal roundtrip; this error is the Marshal leg failing for an individual value. It means one of the config struct's leaf values is of a type yaml.v3 cannot encode — chan, func, or a type whose MarshalYAML errors. Stock colima config uses plain scalars/slices/maps, so this arises from fork-added fields of unsupported types.

Source

Thrown at util/yamlutil/yaml.go:91

			case map[string]any:
			case map[string]string:

			default:
				continue
			}
		}

		// nil slices are converted to untyped nil to encode as `null` instead of `[]`.
		// this preserves nil vs empty slice distinction when the yaml is loaded back.
		if v := reflect.ValueOf(val); v.Kind() == reflect.Slice && v.IsNil() {
			val = nil
		}

		// lazy way, delegate node construction to the yaml library via a roundtrip.
		// no performance concern as only one file is being read
		b, err := yaml.Marshal(val)
		if err != nil {
			return nil, fmt.Errorf("unexpected error nested value encoding: %w", err)
		}
		var newNode yaml.Node
		if err := yaml.Unmarshal(b, &newNode); err != nil {
			return nil, fmt.Errorf("unexpected error during yaml node traversal: %w", err)
		}

		if l := len(newNode.Content); l != 1 {
			return nil, fmt.Errorf("unexpected error during yaml node traversal: doc has multiple children of len %d", l)
		}
		*node = *newNode.Content[0]
	}

	b, err := encode(root)
	if err != nil {
		return nil, fmt.Errorf("error encoding yaml file: %w", err)
	}

	return b, nil

View on GitHub (pinned to c3a5f9184d)

Solutions

  1. Find the offending field from the wrapped error (it names the type) and change it to a serializable type (string, int, bool, slices, maps)
  2. Tag non-serialized fields with `yaml:"-"` so they are skipped during config save
  3. Implement yaml.Marshaler on the custom type to control its encoding
  4. Keep config.Config limited to plain data; keep handles in a separate runtime struct

Example fix

// before
type Config struct {
    Runtime chan string `yaml:"runtime"` // marshal fails
}

// after
type Config struct {
    Runtime string `yaml:"runtime"`
    dispatch chan string `yaml:"-"`
}
Defensive patterns

Strategy: validation

Validate before calling

// assert a config value is YAML-encodable before saving
if _, err := yaml.Marshal(val); err != nil {
    return fmt.Errorf("config field of unsupported type: %w", err)
}

Try / catch

if err := util.Save(cfg, file); err != nil {
    if strings.Contains(err.Error(), "nested value encoding") {
        // a config value has an unsupported type; the wrapped cause names it
        return fmt.Errorf("config contains unserializable value — see cause: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Adding a config field of type chan, func, or a struct with a failing MarshalYAML, then running any code path that saves the config (colima start/stop with settings changes).

Common situations: Forks extending config.Config with runtime handles (loggers, cancellations) instead of serializable settings; embedding interfaces backed by non-serializable implementations.

Related errors


AI-assisted analysis of abiosoft/colima@c3a5f9184d (2026-08-15). Data as JSON: /api/errors/dcdc863759ffaa61. Report an issue: GitHub.