apache/beam · error · AssertionError
Encountered unhashable element
Error message
Encountered unhashable element: {}. What it means
assertUnhashableCountEqual compares multisets of possibly-unhashable Beam PCollection elements by converting each element to a hashable representation via _to_hashable. The helper handles dicts/lists/sets and numpy arrays, but raises AssertionError for any other unhashable type it does not know how to convert.
Solutions
- Make the element type hashable by implementing __hash__ (and __eq__) on the custom class
- Convert unsupported unhashable containers to supported ones (dict/list/set/ndarray) before asserting
- Use a different assertion (e.g., sort elements by a key and compare lists) for exotic types
Example fix
# before assert_that(res, extra_assertion=assertUnhashableCountEqual(expected_custom_objects)) # after class MyRecord: def __eq__(self, other): return self.x == other.x def __hash__(self): return hash(self.x) # now hashable; helper won't raise assert_that(res, extra_assertion=assertUnhashableCountEqual(expected))
Defensive patterns
Strategy: type-guard
Validate before calling
import numpy as np
def all_elements_supported(elements) -> bool:
return all(
isinstance(e, (dict, list, set, frozenset, np.ndarray)) or
(hasattr(e, '__hash__') and hash(e) is not None)
for e in elements
) Type guard
def is_hashable_or_supported(el) -> bool:
import numpy as np
if isinstance(el, (dict, list, set, frozenset, np.ndarray)):
return True
try:
hash(el)
return True
except TypeError:
return False Try / catch
try:
assertUnhashableCountEqual(expected, actual)
except AssertionError as e:
if 'Encountered unhashable element' in str(e):
logging.error('Convert custom unhashable types to dict/list/ndarray or add __hash__.')
else:
raise Prevention
- Give test-element classes __hash__ and __eq__
- Restrict test outputs to types supported by _to_hashable (dict/list/set/ndarray) or hashable builtins
- Prefer sorted-key list comparison for custom objects
When it happens
Trigger: Calling assertUnhashableCountEqual with expected or actual elements containing unhashable objects other than dict/list/set/np.ndarray — e.g. custom class instances, or containers nested beyond the cases _to_hashable handles recursively.
Common situations: Testing pipelines outputting custom class instances or sets of custom objects; comparing elements containing nested custom containers; using the assertion on types the helper wasn't designed for.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- At most one of --create_test and --fix_tests may be…
- f'allowed_sources of test specification
- f'Non-mocked source at line
- f'test specification
- f'test specification
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/ead0e5f698c4d1c9.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/python/apache_beam/testing/extra_assertions.py:53
try:
hash(element)
return element
except TypeError:
pass
if isinstance(element, list):
return tuple(self._to_hashable(e) for e in element)
if isinstance(element, dict):
hashable_elements = []
for key, value in sorted(element.items(), key=lambda t: hash(t[0])):
hashable_elements.append((key, self._to_hashable(value)))
return tuple(hashable_elements)
if isinstance(element, np.ndarray):
return element.tobytes()
raise AssertionError("Encountered unhashable element: {}.".format(element))
View on GitHub (pinned to 12126d8942)