{"record":{"id":"5f4b6ece47e9baf0","repo":"apache/beam","slug":"passert-hash-v-v-v-want-v-v","errorCode":null,"errorMessage":"passert.Hash(%v) = (%v,%v), want (%v,%v)","messagePattern":"passert\\.Hash\\((.+?)\\) = \\((.+?),(.+?)\\), want \\((.+?),(.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/testing/passert/hash.go","lineNumber":63,"sourceCode":"\nfunc (f *hashFn) ProcessElement(_ int, lines func(*string) bool) error {\n\tvar col []string\n\tvar str string\n\tfor lines(&str) {\n\t\tcol = append(col, str)\n\t}\n\tsort.Strings(col)\n\n\tmd5W := md5.New()\n\tfor _, str := range col {\n\t\tif _, err := md5W.Write([]byte(str)); err != nil {\n\t\t\tpanic(err) // cannot fail\n\t\t}\n\t}\n\thash := base64.StdEncoding.EncodeToString(md5W.Sum(nil))\n\n\tif f.Size != len(col) || f.Hash != hash {\n\t\treturn errors.Errorf(\"passert.Hash(%v) = (%v,%v), want (%v,%v)\", f.Name, len(col), hash, f.Size, f.Hash)\n\t}\n\treturn nil\n}\n","sourceCodeStart":45,"sourceCodeEnd":67,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/testing/passert/hash.go#L45-L67","documentation":"passert.Hash asserts both the size and the base64-encoded MD5 hash of a PCollection's concatenated element bytes. errFn.ProcessElement fails with 'passert.Hash(%v) = (%v,%v), want (%v,%v)' when either the observed length or hash differs from the expectation.","triggerScenarios":"The serialized element bytes differ from what the expectation was computed against — element values, ordering, or the coder changed, altering len(col) or the MD5 digest.","commonSituations":"Coder or serialization format changed between library versions; nondeterministic element order; upstream data or transforms modified content.","solutions":["Compare the observed (size, hash) in the message with expected to see whether content or length changed.","If the change is intentional, recompute and update the expected hash/size in the test.","Make element ordering deterministic (sort before hashing) if order varies.","Check for coder changes that alter serialized bytes."],"exampleFix":"// before\npassert.Hash(s, col, \"c29832...\", 42)\n// after\n// recompute expected hash after a legitimate data/coder change:\npassert.Hash(s, col, \"9f86d0...\", 42)","handlingStrategy":"try-catch","validationCode":"h := md5.Sum(serializedBytes)\nwant := base64.StdEncoding.EncodeToString(h[:])\nif want != expectedHash {\n\tt.Fatalf(\"expected hash stale: have %s want %s\", want, expectedHash)\n}","typeGuard":null,"tryCatchPattern":"if err := beamx.Execute(ctx, p); err != nil {\n\tif strings.Contains(err.Error(), \"passert.Hash\") {\n\t\t// diff observed (len,hash) vs expected; recompute expectation if change is intentional\n\t}\n}","preventionTips":["Recompute expected hashes whenever coders or data change.","Sort elements before hashing if order is nondeterministic.","Pin library versions in test environments to avoid coder drift."],"tags":["go","beam","testing","passert","hash"],"backgroundTag":"checksum-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"}