apache/beam · error
cannot make schema for type %v as it has an embedded field o
Error message
cannot make schema for type %v as it has an embedded field of a pointer to an unexported type %v. See https://golang.org/issue/21357
What it means
When converting a Go struct into a schema, ignoreField rejects structs containing an embedded field that is a pointer to an unexported type. Because the schema decoder creates values reflectively, it cannot construct such fields (golang/go#21357), so registration fails early with this message.
Source
Thrown at sdks/go/pkg/beam/core/runtime/graphx/schema/schema.go:181
}
return false
}
func ignoreField(t reflect.Type, sf reflect.StructField) (ignore, isAnon bool, err error) {
isUnexported := sf.PkgPath != ""
if sf.Anonymous {
ft := sf.Type
if ft.Kind() == reflect.Ptr {
// If a struct embeds a pointer to an unexported type,
// it is not possible to set a newly allocated value
// since the field is unexported.
//
// See https://golang.org/issue/21357
//
// Since the values are created by the decoder reflectively,
// fail early here.
if isUnexported {
return false, false, errors.Errorf("cannot make schema for type %v as it has an embedded field of a pointer to an unexported type %v. See https://golang.org/issue/21357", t, ft.Elem())
}
ft = ft.Elem()
}
if isUnexported && ft.Kind() != reflect.Struct {
// Ignore embedded fields of unexported non-struct types.
return true, true, nil
}
// Do not ignore embedded fields of unexported struct types
// since they may have exported fields.
return false, true, nil
}
if isUnexported {
// Schemas can't handle unexported fields at all.
return true, false, nil
}
if implements(sf.Type, sdfRtrackerType) {
// ignoring sdf.Rtracker interface
return true, false, nilView on GitHub (pinned to 12126d8942)
Solutions
- Export the embedded type or embed a value/exported pointer instead of a pointer to an unexported type.
- Register an explicit custom coder for the outer type so schema conversion is bypassed.
- Flatten the needed fields of the unexported type into exported fields of the outer struct.
Example fix
// before
type Result struct { *config } // config is unexported
// after
type Result struct { Config *Config } // Config exported Defensive patterns
Strategy: validation
Validate before calling
func hasUnexportedEmbeddedPtr(t reflect.Type) bool {
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
if f.Anonymous && f.Type.Kind() == reflect.Ptr {
return !f.Type.Elem().IsExported == nil // elem type unexported
}
}
return false
} Try / catch
if err != nil {
if strings.Contains(err.Error(), "pointer to an unexported type") {
// restructure the type or register a custom coder
}
} Prevention
- Never embed pointers to unexported types in pipeline data structs
- Run schema conversion checks in CI on all emitted types
- Flatten unexported helper types into exported fields
When it happens
Trigger: registerType or structToSchema walks a struct type that embeds, e.g. `*privateType` where privateType is unexported, while generating the schema.
Common situations: Pipelines whose DoFns emit structs embedding pointers to unexported types (common with generated or package-private helper types); passing such types to beam.RowEncoder/schema conversion.
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
- panicked: %v
- type is of kind %v
- unlisted kind %v for type %v reached.
- unable to convert map value type
- Unable to generate coder for schema {schema}
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/60e7b8f45c1e3038.
Report an issue: GitHub.