{"record":{"id":"8882679dd90a3f9a","repo":"apache/beam","slug":"observed-pcollection-has-incompatible-type-v","errorCode":null,"errorMessage":"observed PCollection has incompatible type: %v","messagePattern":"observed PCollection has incompatible type: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/testing/passert/floats.go","lineNumber":62,"sourceCode":"}\n\n// TryEqualsFloat checks that two PCollections of floats are equal, with each element\n// being within a specified threshold of its corresponding element. Both PCollections\n// are loaded into memory, sorted, and compared element by element. Returns an error if\n// the PCollection types are complex or non-numeric.\nfunc TryEqualsFloat(s beam.Scope, observed, expected beam.PCollection, threshold float64) error {\n\terrorStrings := []string{}\n\tobservedT := beam.ValidateNonCompositeType(observed)\n\tif obsErr := validateNonComplexNumber(observedT.Type()); obsErr != nil {\n\t\terrorStrings = append(errorStrings, fmt.Sprintf(\"observed PCollection has incompatible type: %v\", obsErr))\n\t}\n\texpectedT := beam.ValidateNonCompositeType(expected)\n\tvalidateNonComplexNumber(expectedT.Type())\n\tif expErr := validateNonComplexNumber(expectedT.Type()); expErr != nil {\n\t\terrorStrings = append(errorStrings, fmt.Sprintf(\"expected PCollection has incompatible type: %v\", expErr))\n\t}\n\tif len(errorStrings) != 0 {\n\t\treturn errors.New(strings.Join(errorStrings, \"\\n\"))\n\t}\n\ts = s.Scope(fmt.Sprintf(\"passert.EqualsFloat[%v]\", threshold))\n\tbeam.ParDo0(s, &thresholdFn{Threshold: threshold}, beam.Impulse(s), beam.SideInput{Input: observed}, beam.SideInput{Input: expected})\n\treturn nil\n}\n\ntype thresholdFn struct {\n\tThreshold float64\n}\n\nfunc (f *thresholdFn) ProcessElement(_ []byte, observed, expected func(*beam.T) bool) error {\n\tvar observedValues, expectedValues []float64\n\tvar observedInput, expectedInput beam.T\n\tfor observed(&observedInput) {\n\t\tval := toFloat(observedInput)\n\t\tobservedValues = append(observedValues, val)\n\t}\n\tfor expected(&expectedInput) {","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/testing/passert/floats.go#L44-L80","documentation":"passert.EqualsFloat validates that both the observed and expected PCollections hold non-complex numeric types before comparing with a tolerance. If the expected PCollection's element type is not a valid non-complex number (e.g. string, bool, struct, complex128), the returned reason is formatted into 'observed PCollection has incompatible type: %v'. Comparison is refused rather than performed.","triggerScenarios":"Calling EqualsFloat(s, observed, expected) where observed's coder/type is not int/uint/float (or the expected side fails validateNonComplexNumber); TestEqualsFloat_nonNumeric exercises exactly this path.","commonSituations":"Feeding a PCollection of strings or structs into EqualsFloat; upstream ParDo emitting interface/any values; accidentally passing the wrong PCollection variable.","solutions":["Ensure the observed PCollection's elements are Go numeric types (int*, uint*, float*)","Insert a beam.ParDo converting elements to float64 before asserting","Use passert.Equals for non-numeric collections instead of EqualsFloat","Check the upstream DoFn's emit type matches the intended numeric type"],"exampleFix":"// before\npassert.EqualsFloat(s, stringCol, 3.14) // incompatible type: string\n// after\nnums := beam.ParDo(s, &parseFloatFn{}, stringCol) // emits float64\npassert.EqualsFloat(s, nums, 3.14)","handlingStrategy":"type-guard","validationCode":"// verify the observed PCollection element type before asserting\nt := observed.Type().Type()\nswitch t.Kind() {\ncase reflect.Int, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64:\n\t// ok\ndefault:\n\treturn fmt.Errorf(\"observed PCollection has incompatible type: %v\", t)\n}","typeGuard":"func isNumericCollection(col beam.PCollection) bool {\n\tk := col.Type().Type().Kind()\n\treturn k >= reflect.Int && k <= reflect.Float64\n}","tryCatchPattern":"if err := passert.EqualsFloat(s, observed, expected); err != nil {\n\tt.Fatalf(\"type validation failed: %v\", err)\n}","preventionTips":["Convert PCollections to float64 with a ParDo before float assertions","Use passert.Equals for non-numeric data","Double-check which PCollection variable is passed as observed vs expected"],"tags":["go","beam","testing","passert","types"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}