{"record":{"id":"b01908cea25a64d3","repo":"apache/beam","slug":"nested-type-in-map-v-not-permitted-in-concrete-types","errorCode":null,"errorMessage":"Nested type in map \"%v\" not permitted in concrete types.","messagePattern":"Nested type in map \"(.+?)\" not permitted in concrete types\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/typex/class.go","lineNumber":143,"sourceCode":"\t\tt == reflectx.Context ||\n\t\tIsUniversal(t) {\n\t\treturn errors.Errorf(\"Special type \\\"%v\\\" not permitted in concrete types\", t)\n\t}\n\n\tswitch t.Kind() {\n\tcase reflect.Invalid, reflect.UnsafePointer, reflect.Uintptr:\n\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)","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/typex/class.go#L125-L161","documentation":"When validating a map type, isConcrete recursively checks the map's element and key types. If either nested type is not concrete, the error is wrapped with 'Nested type in map ...' to point at the containing map. This is the contextual wrapper revealing which map type in your type graph contains the offending key/value.","triggerScenarios":"Declaring element types like map[string]chan int, map[unsafe.Pointer]X, map[string]func(), or maps nested inside structs/slices where the value or key type fails isConcrete.","commonSituations":"Event structs with map[string]interface{} (interface may be fine, but nested chan/func values are not); lookup tables keyed or valued by pointers; JSON-decoded payloads holding func/channel fields.","solutions":["Read the wrapped cause chain (errors.Unwrap) to find the leaf offending kind (chan, func, unsafe.Pointer, etc.).","Replace the offending map key/value type with a serializable type.","Unexport the offending field if it is internal runtime state and should be skipped by validation.","Validate intermediate types with typex.CheckConcrete before assembling larger element types."],"exampleFix":"// before\ntype State struct {\n    Handlers map[string]func()\n}\n\n// after\ntype State struct {\n    HandlerNames []string\n}","handlingStrategy":"validation","validationCode":"mv := reflect.TypeOf(myMapElem)\nif err := typex.CheckConcrete(mv); err != nil {\n    return fmt.Errorf(\"map element type rejected: %w\", err)\n}","typeGuard":"func mapValueSafe(t reflect.Type) bool {\n    return t.Kind() == reflect.Map && typex.IsConcrete(t)\n}","tryCatchPattern":null,"preventionTips":["Follow errors.Unwrap chains to find the leaf offending nested type.","Keep map keys/values to serializable kinds (string, int, struct of such).","Unexport runtime-only map fields."],"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"}