apache/beam · error
Unexpected number type
Error message
Unexpected number type: %v
What it means
In Apache Beam Go SDK's stats package, maxPerKey/Mean-like helpers dispatch to a numeric-specific max function via a generated switch on reflect.Type. If the requested type does not correspond to any generated instantiation (int, int8..., float64, etc.), the default branch panics. This is a defensive check that the API was only called for supported numeric types.
Solutions
- Ensure the input PCollection elements are one of the supported numeric types (ints, uints, float32/float64 as generated in the template).
- Pre-map the PCollection to a supported numeric type with beam.Map before applying stats.Max.
- Check for type alias/defined-type mismatches and convert with explicit casts.
- If a legit numeric type is missing, regenerate templates or extend the stats package's X list for that type.
Example fix
// before
words := beam.ParDo(s, func(w string) string { return w }, in)
stats.Max(s, words) // panics: string
// after
lens := beam.Map(s, func(w string) int { return len(w) }, in)
stats.Max(s, lens) Defensive patterns
Strategy: validation
Validate before calling
// Guard: only call stats.Max on supported numeric element types
func maxSupported(c beam.PCollection) bool {
switch c.Type().String() {
case "int", "int8", "int16", "int32", "int64",
"uint", "uint8", "uint16", "uint32", "uint64",
"float32", "float64":
return true
}
return false
} Type guard
func isNumericForStats(v any) bool {
switch reflect.ValueOf(v).Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
reflect.Float32, reflect.Float64:
return true
}
return false
} Try / catch
// Beam panics abort the pipeline; validate eagerly instead.
// If you must catch:
func safeMax(s beam.Scope, col beam.PCollection) (ret beam.PCollection) {
defer func() {
if r := recover(); r != nil {
log.Printf("stats.Max failed: %v", r)
ret = nil
}
}()
return stats.Max(s, col)
} Prevention
- Feed stats.Max only int*/uint*/float* element types.
- Convert non-numeric elements with beam.Map before aggregating.
- Beware defined types (type MyInt int) — cast to base types first.
- Check c.Type() in pipeline construction to fail fast.
When it happens
Trigger: Calling stats.Max (or the MaxPerKey/Max switch dispatcher) with a PCollection whose element type is not one of the generated numeric types — e.g. a struct, string, interface, uint64 on some builds, or an unnamed/aliased type whose reflect.String() doesn't match the case list.
Common situations: Feeding stats.Max a PCollection of strings or custom types, using type aliases that produce unexpected reflect type strings, or pipeline reshaping that loses the concrete numeric type (element type becomes interface{}).
Related errors
- Unexpected number type
- Unexpected number type
- bad output type
- Node type not bound
- observed PCollection has incompatible type
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/2d58c6d2ce3d53f2.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/transforms/stats/max_switch.tmpl:30
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package stats
import (
"fmt"
"reflect"
)
func findMaxFn(t reflect.Type) any {
switch t.String() {
{{- range .X}}
case "{{.Type}}":
return max{{.Name}}Fn
{{- end}}
default:
panic(fmt.Sprintf("Unexpected number type: %v", t))
}
}
{{range .X}}
func max{{.Name}}Fn(x, y {{.Type}}) {{.Type}} {
if x > y {
return x
}
return y
}
{{end}}
View on GitHub (pinned to 12126d8942)