{"record":{"id":"d752b5f05b32699b","repo":"apache/beam","slug":"type-must-be-a-non-complex-number-v-util","errorCode":null,"errorMessage":"type must be a non-complex number: %v","messagePattern":"type must be a non-complex number: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/transforms/stats/util.go","lineNumber":55,"sourceCode":"\tvalidateNonComplexNumber(t.Type())\n\n\t// Do a pipeline-construction-time type switch to select the right\n\t// runtime operation.\n\treturn beam.Combine(s, makeCombineFn(t.Type()), col)\n}\n\nfunc combinePerKey(s beam.Scope, makeCombineFn func(reflect.Type) any, col beam.PCollection) beam.PCollection {\n\t_, t := beam.ValidateKVType(col)\n\tvalidateNonComplexNumber(t.Type())\n\n\t// Do a pipeline-construction-time type switch to select the right\n\t// runtime operation.\n\treturn beam.CombinePerKey(s, makeCombineFn(t.Type()), col)\n}\n\nfunc validateNonComplexNumber(t reflect.Type) {\n\tif !reflectx.IsNumber(t) || reflectx.IsComplex(t) {\n\t\tpanic(fmt.Sprintf(\"type must be a non-complex number: %v\", t))\n\t}\n}\n","sourceCodeStart":37,"sourceCodeEnd":58,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/transforms/stats/util.go#L37-L58","documentation":"stats.Mean, MeanPerKey and the internal combine helpers call validateNonComplexNumber to assert the element type is a number and not a complex type. If reflectx.IsNumber is false or the type is complex128/complex64, the library panics because averaging is undefined for those types.","triggerScenarios":"Calling stats.Mean(s, col) or stats.MeanPerKey(s, keyCol, valCol) where the value PCollection's element type is a string, bool, struct, or complex64/complex128.","commonSituations":"Averaging complex numbers from signal-processing pipelines; passing a struct holding a numeric field instead of the field itself; keys/value columns swapped in MeanPerKey so the value type is a non-numeric key type.","solutions":["Extract the numeric field you actually want to average with a ParDo before calling stats.Mean.","Convert string/other encodings to float64 before averaging.","For complex data, compute real/imaginary means separately or write a custom combine function."],"exampleFix":"// before\nstats.MeanPerKey(s, keyCol, recordCol) // value is Record, not a number\n\n// after\nvalues := beam.ParDo(s, func(r Record) float64 { return r.Score }, recordCol)\nstats.MeanPerKey(s, keyCol, values)","handlingStrategy":"validation","validationCode":"t := reflect.TypeOf(val)\nif t.Kind() == reflect.Complex64 || t.Kind() == reflect.Complex128 ||\n    (t.Kind() < reflect.Int || t.Kind() > reflect.Float64) {\n    return fmt.Errorf(\"stats.Mean needs a non-complex number, got %v\", t)\n}","typeGuard":"func isNonComplexNumber(v any) bool {\n    k := reflect.TypeOf(v).Kind()\n    return k >= reflect.Int && k <= reflect.Float64\n}","tryCatchPattern":null,"preventionTips":["In MeanPerKey, double-check you pass the value column (numeric), not the key column.","Extract numeric fields from structs before averaging.","Handle complex data by splitting into real/imaginary float64 streams."],"tags":["go","apache-beam","panic","type-validation","stats"],"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"}