BoundaryML/baml · error

encoding map value: %w

Error message

encoding map value: %w

What it means

Contextual wrapper added by encodeMap when the value stored under some key fails encodeValue. The wrapped cause names the real problem (unsupported type, failed serializer, etc.); the map iteration order determines which key surfaces first, so failures may appear nondeterministic across runs.

Source

Thrown at engine/language_client_go/baml_go/serde/encode.go:220

			return nil, fmt.Errorf("encoding list element %d: %w", i, err)
		}
		values[i] = elemOffset
	}

	return &cffi.HostListValue{
		Values: values,
	}, nil
}

// encodeMap now accepts and passes TypeMap
func encodeMap(mapValue reflect.Value) (*cffi.HostMapValue, error) {

	entries := make([]*cffi.HostMapEntry, 0, mapValue.Len())
	for _, key := range mapValue.MapKeys() {
		value := mapValue.MapIndex(key)
		valueHolder, err := encodeValue(value.Interface())
		if err != nil {
			return nil, fmt.Errorf("encoding map value: %w", err)
		}

		switch key.Kind() {
		case reflect.String:
			// Go doesn't have enums, so we can't detect them here
			entries = append(entries, &cffi.HostMapEntry{
				Key:   &cffi.HostMapEntry_StringKey{StringKey: key.String()},
				Value: valueHolder,
			})
		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			entries = append(entries, &cffi.HostMapEntry{
				Key:   &cffi.HostMapEntry_IntKey{IntKey: key.Int()},
				Value: valueHolder,
			})
		case reflect.Bool:
			entries = append(entries, &cffi.HostMapEntry{
				Key:   &cffi.HostMapEntry_BoolKey{BoolKey: key.Bool()},
				Value: valueHolder,

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Inspect the wrapped cause to identify the failing value type
  2. Iterate and type-check map values before the call to find bad entries deterministically
  3. Convert or remove unsupported values; add serializers for custom types
  4. Flatten nested custom structs into maps of primitives

Example fix

// before
m := map[string]any{"ok": 1, "bad": make(chan int)}
b.Fn(ctx, m)
// after
m := map[string]any{"ok": 1}
b.Fn(ctx, m)
Defensive patterns

Strategy: validation

Validate before calling

func checkMapValues(m map[string]any) error { for k, v := range m { if err := checkEncodable(v); err != nil { return fmt.Errorf("key %q: %w", k, err) } }; return nil }

Type guard

func isEncodable(v any) bool { switch v.(type) { case string, int, int64, float64, bool, nil: return true }; k := reflect.ValueOf(v).Kind(); return k == reflect.Slice || k == reflect.Map }

Try / catch

if err := b.Fn(ctx, m); err != nil {
  if strings.Contains(err.Error(), "encoding map value") { /* iterate keys and validate each value */ }
}

Prevention

When it happens

Trigger: String-keyed map inputs (or dynamic class fields) whose values include unencodable types — nested raw structs, Checked/StreamState values, or internal objects with failing Encode().

Common situations: map[string]any payloads assembled from multiple sources; maps mixing valid primitives with one bad custom type; JSON round-tripped data containing unexpected types.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/b1cba9690c2021a3. Report an issue: GitHub.