{"record":{"id":"c43e8437f23b4f63","repo":"apache/beam","slug":"pcollections-of-different-lengths-got-v-expected-v","errorCode":null,"errorMessage":"PCollections of different lengths, got %v expected %v","messagePattern":"PCollections of different lengths, got (.+?) expected (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/testing/passert/floats.go","lineNumber":85,"sourceCode":"}\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) {\n\t\tval := toFloat(expectedInput)\n\t\texpectedValues = append(expectedValues, val)\n\t}\n\tif len(observedValues) != len(expectedValues) {\n\t\treturn errors.Errorf(\"PCollections of different lengths, got %v expected %v\", len(observedValues), len(expectedValues))\n\t}\n\tsort.Float64s(observedValues)\n\tsort.Float64s(expectedValues)\n\tvar tooLow, tooHigh []string\n\tfor i := 0; i < len(observedValues); i++ {\n\t\tdelta := observedValues[i] - expectedValues[i]\n\t\tif delta > f.Threshold {\n\t\t\ttooHigh = append(tooHigh, fmt.Sprintf(\"%v > %v,\", observedValues[i], expectedValues[i]))\n\t\t} else if delta < f.Threshold*-1 {\n\t\t\ttooLow = append(tooLow, fmt.Sprintf(\"%v < %v,\", observedValues[i], expectedValues[i]))\n\t\t}\n\t}\n\tif len(tooLow)+len(tooHigh) == 0 {\n\t\treturn nil\n\t}\n\terrorStrings := []string{}\n\tif len(tooLow) != 0 {\n\t\terrorStrings = append(errorStrings, fmt.Sprintf(\"values below expected: %v\", tooLow))","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/testing/passert/floats.go#L67-L103","documentation":"passert.Floats compares observed vs expected PCollections of floats. The assertion first checks that both sides contain the same number of elements; this error fires when the lengths differ, before any value-level comparison.","triggerScenarios":"passert.FloatsEquals / AllWithinBounds runs where the observed PCollection has more or fewer elements than the expected one — an element was dropped or duplicated upstream.","commonSituations":"A filter or expansion step changes element counts; windowing drops or duplicates elements; test expectations updated on one side only.","solutions":["Count elements on both sides and find the transform adding/removing elements; fix it.","Align expectations with intended counts if behavior legitimately changed.","Check windowing/triggering so elements are not lost or emitted twice.","Derive both PCollections from the same deterministic input."],"exampleFix":"// before\nfiltered := beam.Filter(s, func(x float64) bool { return x > 0 })\npassert.FloatsEquals(s, expected, filtered) // filter drops negatives expected contains\n// after\nout := beam.ParDo(s, normalizeFn, in) // 1:1 element counts\npassert.FloatsEquals(s, expected, out)","handlingStrategy":"validation","validationCode":"if len(observed) != len(expected) {\n\tt.Fatalf(\"element counts differ before assertion: %d vs %d\", len(observed), len(expected))\n}","typeGuard":null,"tryCatchPattern":"if err := beamx.Execute(ctx, p); err != nil {\n\tif strings.Contains(err.Error(), \"PCollections of different lengths\") {\n\t\t// find the transform dropping/duplicating elements and fix it\n\t}\n}","preventionTips":["Avoid filters or expansions in assertion input paths unless mirrored on both sides.","Use deterministic windowing in tests.","Derive expected values from the same input data."],"tags":["go","beam","testing","passert","floats"],"backgroundTag":"assertion-failed","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"}