apache/beam · error

unable to convert map key type

Error message

unable to convert map key type

What it means

Wrapper error raised when the key type of a MapType field fails conversion in Registry.fieldTypeToReflectType. Beam/Go require map keys to be comparable and schema-representable; if the key's FieldType cannot be turned into a reflect.Type, this error names the map context. Note the adjacent comment: reflect.MapOf panics for invalid keys (slices/iterables), so key failures should be caught here first.

Solutions

  1. Inspect the wrapped error to find why the key type failed
  2. Change the map key to a schema-supported comparable atomic (string, int, bool, bytes)
  3. Register the key's logical type so it resolves to a comparable Go type
  4. Restructure the schema to use a repeated row of {key,value} instead of a map when keys aren't convertible

Example fix

// before: map with array key
// after: represent as list of pairs
fields: [ {name: "entries", type: array<row{key: string, value: int64}>} ]
Defensive patterns

Strategy: validation

Validate before calling

func mapKeysSchemaSafe(s *pipepb.Schema) error {
  for _, f := range s.GetFields() {
    if mt := f.GetType().GetMapType(); mt != nil {
      if mt.GetKeyType().GetAtomicType() == pipepb.AtomicType_ATOMIC_TYPE_UNSPECIFIED {
        return fmt.Errorf("map field %q key must be an atomic type", f.GetName())
      }
    }
  }
  return nil
}

Try / catch

if err != nil && strings.Contains(err.Error(), "unable to convert map key type") {
  return fmt.Errorf("map key must be a comparable atomic: %w", err)
}

Prevention

When it happens

Trigger: toType/fieldToStructField encountering a schema MapType whose KeyType fails fieldTypeToReflectType — e.g. key is an array type, logical type resolving to a slice, or unknown atomic.

Common situations: Schemas produced by other SDKs (Java/Python allow richer map key logical types) or hand-built schemas with non-convertible keys being loaded via ToType in Go.

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 apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/20463d1d369d8de5. Report an issue: GitHub.

Appendix: source

Thrown at sdks/go/pkg/beam/core/runtime/graphx/schema/schema.go:778

func (r *Registry) fieldTypeToReflectType(sft *pipepb.FieldType, opts []*pipepb.Option) (reflect.Type, error) {
	var t reflect.Type
	switch sft.GetTypeInfo().(type) {
	case *pipepb.FieldType_AtomicType:
		var ok bool
		if t, ok = atomicTypeToReflectType[sft.GetAtomicType()]; !ok {
			return nil, errors.Errorf("unknown atomic type: %v", sft.GetAtomicType())
		}
	case *pipepb.FieldType_ArrayType:
		rt, err := r.fieldTypeToReflectType(sft.GetArrayType().GetElementType(), nil)
		if err != nil {
			return nil, errors.Wrap(err, "unable to convert array element type")
		}
		t = reflect.SliceOf(rt)
	case *pipepb.FieldType_MapType:
		kt, err := r.fieldTypeToReflectType(sft.GetMapType().GetKeyType(), nil)
		if err != nil {
			return nil, errors.Wrap(err, "unable to convert map key type")
		}
		vt, err := r.fieldTypeToReflectType(sft.GetMapType().GetValueType(), nil)
		if err != nil {
			return nil, errors.Wrap(err, "unable to convert map value type")
		}
		t = reflect.MapOf(kt, vt) // Panics for invalid map keys (slices/iterables)
	case *pipepb.FieldType_RowType:
		rt, err := r.toType(sft.GetRowType().GetSchema())
		if err != nil {
			return nil, errors.Wrapf(err, "unable to convert row type: %v", sft.GetRowType().GetSchema().GetId())
		}
		t = rt
	// case *pipepb.FieldType_IterableType:
	// TODO(BEAM-9615): handle IterableTypes (eg. CoGBK values)

	case *pipepb.FieldType_LogicalType:
		lst := sft.GetLogicalType()
		identifier := lst.GetUrn()

View on GitHub (pinned to 12126d8942)