apache/beam · error

cannot convert to schema. FromType only converts structs to…

Error message

cannot convert %v to schema. FromType only converts structs to schemas

What it means

FromType only converts Go struct types into Beam Row schemas. If the passed reflect.Type (after skipping pointers) is not of Kind reflect.Struct, this error is returned directly. It signals API misuse: FromType is the wrong entry point for non-struct types.

Solutions

  1. Pass a struct type (or pointer to struct) to FromType.
  2. Wrap non-struct leaf types in a struct field or register a LogicalType via RegisterLogicalType.
  3. Assert before calling: reflectx.SkipPtr(t).Kind() == reflect.Struct.

Example fix

// before
t := reflect.TypeOf([]string{})
schm, err := reg.FromType(t) // error
// after
type Rows struct { Values []string }
schm, err := reg.FromType(reflect.TypeOf(Rows{}))
Defensive patterns

Strategy: type-guard

Validate before calling

t := reflect.TypeOf(x)
if reflectx.SkipPtr(t).Kind() != reflect.Struct {
    return nil, fmt.Errorf("%v is not a struct; FromType requires structs", t)
}

Type guard

func isSchemaConvertibleStruct(v interface{}) bool {
    return reflectx.SkipPtr(reflect.TypeOf(v)).Kind() == reflect.Struct
}

Try / catch

schm, err := reg.FromType(t)
if err != nil && strings.Contains(err.Error(), "only converts structs") {
    return nil, fmt.Errorf("wrap %v in a struct or register a logical type", t)
}

Prevention

When it happens

Trigger: Calling Registry.FromType(reflect.TypeOf(x)) where x is a slice, map, string, int, or other non-struct (pointers are skipped, so the pointed-to kind is what matters).

Common situations: Trying to schema-encode a []byte, map, or primitive; accidentally passing reflect.TypeOf on a slice variable; converting wrapper types instead of their row structs.

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/cec22f9f976fce18. Report an issue: GitHub.

Appendix: source

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

	// empty types have no value for lookups.
	if synth != emptyStructType {
		r.syntheticToUser[synth] = ut
		r.syntheticToUser[reflect.PtrTo(synth)] = reflect.PtrTo(ut)
	}
	if ut != emptyStructType {
		r.syntheticToUser[ut] = ut
		r.syntheticToUser[reflect.PtrTo(ut)] = reflect.PtrTo(ut)
	}
}

// FromType returns a Beam Schema of the passed in type.
// Returns an error if the type cannot be converted to a Schema.
func (r *Registry) FromType(ot reflect.Type) (*pipepb.Schema, error) {
	if err := r.reconcileRegistrations(); err != nil {
		return nil, errors.Wrap(err, "reconciling for FromType")
	}
	if reflectx.SkipPtr(ot).Kind() != reflect.Struct {
		return nil, errors.Errorf("cannot convert %v to schema. FromType only converts structs to schemas", ot)
	}
	return r.fromType(ot)
}

func (r *Registry) logicalTypeToFieldType(t reflect.Type) (*pipepb.FieldType, string, error) {
	// Check if a logical type was registered that matches this struct type directly
	// and if so, extract the schema from it for use.
	if lID, ok := r.logicalTypeIdentifiers[t]; ok {
		lt := r.logicalTypes[lID]
		ftype, err := r.reflectTypeToFieldType(lt.StorageType())
		if err != nil {
			return nil, "", errors.Wrapf(err, "unable to convert LogicalType[%v]'s storage type %v for Go type of %v to a schema", lID, lt.StorageType(), lt.GoType())
		}
		return ftype, lID, nil
	}
	for _, lti := range r.logicalTypeInterfaces {
		if !t.Implements(lti) {
			continue

View on GitHub (pinned to 12126d8942)