{"record":{"id":"ed8c3d9b7a66a7e6","repo":"apache/beam","slug":"cannot-make-schema-encoder-for-type-v-as-it-has-unexported","errorCode":null,"errorMessage":"cannot make schema encoder for type %v as it has unexported fields such as %s.","messagePattern":"cannot make schema encoder for type (.+?) as it has unexported fields such as (.+?)\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/coder/row_encoder.go","lineNumber":318,"sourceCode":"\t\t\t\t// See https://golang.org/issue/21357\n\t\t\t\t//\n\t\t\t\t// Since the values are created by this package reflectively,\n\t\t\t\t// there's no work around like pre-allocating the field\n\t\t\t\t// manually.\n\t\t\t\tif isUnexported {\n\t\t\t\t\treturn nil, errors.Errorf(\"cannot make schema encoder 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())\n\t\t\t\t}\n\t\t\t\tft = ft.Elem()\n\t\t\t}\n\t\t\tif isUnexported && ft.Kind() != reflect.Struct {\n\t\t\t\t// Ignore embedded fields of unexported non-struct types.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// Do not ignore embedded fields of unexported struct types\n\t\t\t// since they may have exported fields.\n\t\t} else if isUnexported {\n\t\t\tif b.RequireAllFieldsExported {\n\t\t\t\treturn nil, errors.Errorf(\"cannot make schema encoder for type %v as it has unexported fields such as %s.\", t, sf.Name)\n\t\t\t}\n\t\t\t// Silently ignore, since we can't do anything about it.\n\t\t\t// Add a no-op coder to fill in field index\n\t\t\tcoder.fields = append(coder.fields, typeEncoderFieldReflect{encode: func(rv reflect.Value, w io.Writer) error {\n\t\t\t\treturn nil\n\t\t\t}})\n\t\t\tcontinue\n\t\t}\n\t\tenc, err := b.encoderForSingleTypeReflect(sf.Type)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcoder.fields = append(coder.fields, enc)\n\t}\n\n\treturn func(rv reflect.Value, w io.Writer) error {\n\t\tif err := writeRowHeader(rv, w); err != nil {\n\t\t\treturn err","sourceCodeStart":300,"sourceCodeEnd":336,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/coder/row_encoder.go#L300-L336","documentation":"When RowEncoderBuilder.RequireAllFieldsExported is set, encoding a struct containing unexported fields fails: Beam cannot read or write those fields reflectively, so strict mode errors out instead of silently skipping them.","triggerScenarios":"Calling encoderForStructReflect on a struct with unexported fields while the builder was created with RequireAllFieldsExported = true (e.g. from a strict schema path).","commonSituations":"Users relying on schema coding with idiomatic Go structs that keep private fields; strict coders used in DoFn serialization checks.","solutions":["Export all fields of the struct, or remove unexported fields from the encoded type","Disable RequireAllFieldsExported so unexported fields are skipped with a no-op coder","Implement a custom coder for the type"],"exampleFix":"// before\ntype Rec struct { Name string; secret string }\n// after\ntype Rec struct { Name string; Secret string }","handlingStrategy":"validation","validationCode":"func hasUnexportedFields(t reflect.Type) bool {\n    if t.Kind() != reflect.Struct { return false }\n    for i := 0; i < t.NumField(); i++ {\n        if !t.Field(i).IsExported() { return true }\n    }\n    return false\n}","typeGuard":"func isFullyExported(v any) bool { return !hasUnexportedFields(reflect.TypeOf(v)) }","tryCatchPattern":"if _, err := (coder.RowEncoderBuilder{RequireAllFieldsExported: true}).Build(t); err != nil {\n    return fmt.Errorf(\"strict schema encoding requires exported fields: %w\", err)\n}","preventionTips":["Export all fields of types used as PCollection elements","Only set RequireAllFieldsExported when you control the type","Lint for unexported fields in schema-coded structs"],"tags":["go","beam","reflection","struct","exported-fields"],"backgroundTag":"schema-validation-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}