{"record":{"id":"8668af7a1c446299","repo":"apache/beam","slug":"reference-source-and-provided-list-of-sources-must-produce","errorCode":null,"errorMessage":"Reference source and provided list of sources must produce the same set of records.","messagePattern":"Reference source and provided list of sources must produce the same set of records\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/source_test_utils.py","lineNumber":177,"sourceCode":"    if (type(reference_source_info[0].default_output_coder())\n        != type(source_info[0].default_output_coder())):\n      raise ValueError(\n          'Reference source %r and the source %r must use the same coder. '\n          'They are using %r and %r respectively instead.' % (\n              reference_source_info[0],\n              source_info[0],\n              type(reference_source_info[0].default_output_coder()),\n              type(source_info[0].default_output_coder())))\n    source_records.extend(read_from_source(*source_info))\n\n  if len(reference_records) != len(source_records):\n    raise ValueError(\n        'Reference source must produce the same number of records as the '\n        'list of sources. Number of records were %d and %d instead.' %\n        (len(reference_records), len(source_records)))\n\n  if equal_to(reference_records)(source_records):\n    raise ValueError(\n        'Reference source and provided list of sources must produce the '\n        'same set of records.')\n\n\ndef assert_reentrant_reads_succeed(source_info):\n  \"\"\"Tests if a given source can be read in a reentrant manner.\n\n  Assume that given source produces the set of values ``{v1, v2, v3, ... vn}``.\n  For ``i`` in range ``[1, n-1]`` this method performs a reentrant read after\n  reading ``i`` elements and verifies that both the original and reentrant read\n  produce the expected set of values.\n\n  Args:\n    source_info (Tuple[~apache_beam.io.iobase.BoundedSource, int, int]):\n      a three-tuple that gives the reference\n      :class:`~apache_beam.io.iobase.BoundedSource`, position to start reading\n      at, and a position to stop reading at.\n","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/source_test_utils.py#L159-L195","documentation":"Raised by assert_sources_equal_reference_source when the reference source and the sources under test produce the same number of records but the record sets differ. After count comparison passes, the utility applies the equal_to matcher; if the elements are not identical it raises this error. It means the source under test emits different data (values, order-sensitive mismatches, or corrupt/differently-decoded records) than the reference source.","triggerScenarios":"assert_sources_equal_reference_source succeeds on record counts but equal_to(reference_records)(source_records) detects differing elements between the reference source output and the concatenated output of sources_info.","commonSituations":"A custom source's split ranges overlap (duplicate records) while totals happen to match, records are decoded with a wrong coder, or nondeterministic ordering/transformation inside read() alters values.","solutions":["Diff reference_records vs source_records element-wise to find the first mismatching record.","Fix the source's read() so each range yields exactly the records in [start_position, stop_position) with correct values.","Ensure the source uses the same default_output_coder as the reference (the utils already enforce the coder type earlier).","Check for duplicate ranges across the split sources and eliminate overlaps."],"exampleFix":"# before: overlapping splits duplicate a record at the boundary\nreturn records[start_position:stop_position + 1]\n# after: half-open range [start, stop)\nreturn records[start_position:stop_position]","handlingStrategy":"validation","validationCode":"ref_records = list(read_from_source(*ref_info))\nsrc_records = [r for si in sources_info for r in read_from_source(*si)]\nassert sorted(map(repr, ref_records)) == sorted(map(repr, src_records))","typeGuard":"def uses_same_coder(ref, src):\n    return type(ref.default_output_coder()) == type(src.default_output_coder())","tryCatchPattern":"try:\n    source_test_utils.assert_sources_equal_reference_source(ref_info, sources_info)\nexcept ValueError:\n    diff = list(set(map(repr, ref_records)) ^ set(map(repr, src_records)))\n    logger.error(\"record mismatch, differing: %s\", diff[:10])\n    raise","preventionTips":["Check split ranges for overlaps/duplicates before comparing","Keep the coder identical between reference and test sources","Use deterministic record ordering inside read()"],"tags":["apache-beam","bounded-source","record-mismatch","io-testing"],"backgroundTag":"unexpected-response-shape","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"}