{"record":{"id":"17a941db488250c8","repo":"apache/beam","slug":"invalid-underlying-type-v","errorCode":null,"errorMessage":"Invalid underlying type: %v","messagePattern":"Invalid underlying type: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/typex/fulltype.go","lineNumber":163,"sourceCode":"\t\t\tif isAnyNonKVComposite(components) {\n\t\t\t\tpanic(fmt.Sprintf(\"Invalid to nest composites inside CoGBK: %v\", t))\n\t\t\t}\n\t\t\treturn &tree{class, t, components}\n\t\tcase TimersType:\n\t\t\treturn &tree{class, t, components}\n\t\tcase ShardedKeyType:\n\t\t\tif len(components) != 1 {\n\t\t\t\tpanic(fmt.Sprintf(\"Invalid number of components for ShardedKey: %v, %v\", t, components))\n\t\t\t}\n\t\t\tif components[0].Class() == Composite {\n\t\t\t\tpanic(fmt.Sprintf(\"Invalid to nest composite inside ShardedKey: %v, %v\", t, components))\n\t\t\t}\n\t\t\treturn &tree{class, t, components}\n\t\tdefault:\n\t\t\tpanic(fmt.Sprintf(\"Unexpected composite type: %v\", t))\n\t\t}\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"Invalid underlying type: %v\", t))\n\t}\n}\n\n// NOTE(herohde) 1/26/2018: we allow nested KV types and coders to support the\n// CoGBK translation (using KV<K,KV<int,[]byte>> to encode keyed raw union values)\n// and potentially other uses. We do not have a reasonable way to emit nested KV\n// values, so user functions are still limited to non-nested KVs. Universally-typed\n// KV-values might be simple to allow, for example.\n\nfunc isAnyNonKVComposite(list []FullType) bool {\n\tfor _, t := range list {\n\t\tif t.Class() == Composite && t.Type() != KVType {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/typex/fulltype.go#L145-L181","documentation":"typex.New's outer switch expects the type's Class() to be either Composite or Singleton (the leaf case). Any other class value reaches the default branch and panics with 'Invalid underlying type'. This is a last-resort invariant check that FullType trees are built only from these two classes.","triggerScenarios":"Calling typex.New with a type whose Class() is neither Composite nor Singleton — for example a raw/undetermined class, or a mis-constructed typex.Type. Reached via the public New and its callers (Prefix, CoGroupByKey, CombinePerKey, CombineGlobally, Flatten, GroupByKey).","commonSituations":"Programmatically assembling types from constants and hitting an invalid class value; version skew where a type carries a class value this SDK version does not understand; typos when building types in generated code.","solutions":["Build types via the provided helpers (typex.New, typex.NewKV, etc.) rather than constructing raw class values.","Verify the FullType being passed was produced by this SDK version; regenerate or update code that hardcodes class values.","Align SDK versions across modules to eliminate unknown class encodings."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"func validClass(t typex.Type) bool {\n    c := t.Class()\n    return c == typex.Composite || c == typex.Singleton\n}","typeGuard":null,"tryCatchPattern":"func safeNew(t typex.Type, cs ...typex.FullType) (ft typex.FullType, err error) {\n    defer func() {\n        if r := recover(); r != nil { err = fmt.Errorf(\"typex.New: %v\", r) }\n    }()\n    return typex.New(t, cs...), nil\n}","preventionTips":["Build types via the SDK helpers, never from raw class constants.","Verify FullType provenance when passing types across package boundaries.","Add asserts on Class() in code that constructs types dynamically."],"tags":["go","apache-beam","typex","panic","type-validation"],"backgroundTag":"invalid-enum-value","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"}