{"record":{"id":"2e84a9200cb66e5e","repo":"apache/beam","slug":"nested-type-in-v-v-not-permitted-in-concrete-types","errorCode":null,"errorMessage":"Nested type in %v \"%v\" not permitted in concrete types.","messagePattern":"Nested type in (.+?) \"(.+?)\" not permitted in concrete types\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/typex/class.go","lineNumber":150,"sourceCode":"\t\treturn errors.Errorf(\"Type \\\"%v\\\" of kind \\\"%v\\\" not permitted in concrete types. All types must be manageable.\", t, t.Kind()) // no unmanageable types\n\n\tcase reflect.Chan, reflect.Func:\n\t\treturn errors.Errorf(\"Type \\\"%v\\\" of kind \\\"%v\\\" not permitted in concrete types. All types must be serializable.\", t, t.Kind()) // no unserializable types\n\n\tcase reflect.Map:\n\t\terr := isConcrete(t.Elem(), visited)\n\t\tif err == nil {\n\t\t\terr = isConcrete(t.Key(), visited)\n\t\t}\n\t\tif err != nil {\n\t\t\terr = errors.Wrapf(err, \"Nested type in map \\\"%v\\\" not permitted in concrete types.\", t)\n\t\t}\n\t\treturn err\n\n\tcase reflect.Array, reflect.Slice, reflect.Ptr:\n\t\terr := isConcrete(t.Elem(), visited)\n\t\tif err != nil {\n\t\t\terr = errors.Wrapf(err, \"Nested type in %v \\\"%v\\\" not permitted in concrete types.\", t.Kind(), t)\n\t\t}\n\t\treturn err\n\n\tcase reflect.Struct:\n\t\tfor i := 0; i < t.NumField(); i++ {\n\t\t\t// We ignore private fields under the assumption that they are\n\t\t\t// either not needed or will be coded manually. For combiner\n\t\t\t// accumulators, we need types that need non-trivial coding. Also,\n\t\t\t// Go serialization schemes in general ignore private fields.\n\n\t\t\tf := t.Field(i)\n\t\t\tif len(f.Name) > 0 {\n\t\t\t\tr, _ := utf8.DecodeRuneInString(f.Name)\n\t\t\t\tif unicode.IsUpper(r) {\n\t\t\t\t\terr := isConcrete(f.Type, visited)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn errors.Wrapf(err, \"Nested type in struct \\\"%v\\\" not permitted in concrete types.\", t)\n\t\t\t\t\t}","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/typex/class.go#L132-L168","documentation":"When validating array, slice, or pointer types, isConcrete recursively checks the element type; on failure it wraps the error with 'Nested type in <kind> ...' to identify the containing array/slice/pointer. It localizes the offending type within your element-type graph.","triggerScenarios":"Element types like []*unsafe.Pointer-wrapped structs, []chan Event, [][]func(), or pointers to structs containing chan/func exported fields.","commonSituations":"Slices of records with callback fields; pointer-based object graphs (linked lists with func fields); test fixtures reused as pipeline element types.","solutions":["Follow the wrapped error chain to the leaf type and fix its kind (no chan/func/unsafe.Pointer/uintptr).","Unexport offending fields so isConcrete skips them (private fields are ignored).","Restructure pointer graphs into flat serializable records.","Add a unit test calling typex.CheckConcrete on the element type to fail fast during development."],"exampleFix":"// before\ntype Node struct {\n    Next *Node\n    Emit func(Event)\n}\n\n// after\ntype Node struct {\n    NextID string\n    EmitTarget string\n}","handlingStrategy":"validation","validationCode":"if err := typex.CheckConcrete(reflect.TypeOf(sliceElem)); err != nil {\n    return fmt.Errorf(\"slice/ptr element type rejected: %w\", err)\n}","typeGuard":"func nestedSafe(t reflect.Type) bool {\n    switch t.Kind() {\n    case reflect.Array, reflect.Slice, reflect.Ptr:\n        return typex.IsConcrete(t)\n    }\n    return true\n}","tryCatchPattern":null,"preventionTips":["Flatten pointer graphs into flat serializable records.","Avoid callback/channel fields in nested structs.","Test types with typex.CheckConcrete before use."],"tags":["go","apache-beam","type-system"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}