apache/beam · error
unable to convert LogicalType
Error message
unable to convert LogicalType[%v] using provider for %v schema field
What it means
Raised in Registry.logicalTypeToFieldType when a type t implements a registered logical type interface and that interface's provider function p(t) returns an error. The wrap preserves both the Go type and the interface type, indicating the provider could not produce a storage type for t.
Solutions
- Read the wrapped provider error — it is produced by the provider function.
- Fix the type/value so it satisfies the provider's constraints.
- If it's your provider, return a valid storage type or nil (meaning 'not handled') instead of an error.
- Register a direct LogicalType for the concrete type instead of relying on the interface provider.
Example fix
// before
p := func(t reflect.Type) (reflect.Type, error) { return nil, fmt.Errorf("unsupported %v", t) }
// after
p := func(t reflect.Type) (reflect.Type, error) {
if valid(t) { return reflect.TypeOf([]byte{}), nil }
return nil, nil // not handled, try next provider
} Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := myProvider(reflect.TypeOf(myVal)); err != nil {
return fmt.Errorf("provider rejects type: %w", err)
} Type guard
func implementsLogicalInterface(t reflect.Type, iface reflect.Type) bool { return t.Implements(iface) } Try / catch
schm, err := reg.FromType(t)
if err != nil && strings.Contains(err.Error(), "using provider") {
return nil, fmt.Errorf("provider failed for %v: %w", reflect.TypeOf(t), err)
} Prevention
- Return nil (not an error) from providers when the type is not handled.
- Keep provider constraints simple and value-independent.
- Register direct logical types for known-concrete types.
- Test providers against all concrete types implementing the interface.
When it happens
Trigger: Converting a struct field whose type implements a registered logical type interface where the provider callback errors — typically because the provider rejects that concrete type or its values.
Common situations: Types implementing a logical-type interface incompletely; provider logic asserting value constraints (invalid dates, bad decimal scale) that fail at schema-conversion time during pipeline graph building.
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
- beam.RegisterSchemaProvider: schema type provider for
- invalid logical type, bad id
- LogicalType[ ] has an invalid StorageType
- reconciling for ToType
- unable to convert LogicalType
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/345fd114bb397290.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/runtime/graphx/schema/schema.go:348
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
}
p := r.logicalTypeProviders[lti]
st, err := p(t)
if err != nil {
return nil, "", errors.Wrapf(err, "unable to convert LogicalType[%v] using provider for %v schema field", t, lti)
}
if st == nil {
continue
}
ftype, err := r.reflectTypeToFieldType(st)
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", "interface", st, t)
}
return ftype, t.String(), nil
}
return nil, "", nil
}
// fromType handles if the initial type is a pointer or not WRT lookups against
// registered types and then delegates to structToSchema for most of the conversion.
// For determinism in schema IDs, regardless of whther the original type is a pointer or not,
// both variants are cached for latter reuse.
func (r *Registry) fromType(ot reflect.Type) (*pipepb.Schema, error) {View on GitHub (pinned to 12126d8942)