apache/beam · error · NotImplementedError
NotImplementedError
Error message
NotImplementedError
What it means
iobase.RangeTracker's abstract fraction_to_position() has no default implementation; the base class raises NotImplementedError. Concrete RangeTracker implementations must override it to convert a fraction into a position.
Source
Thrown at sdks/python/apache_beam/io/range_trackers.py:292
if self._last_claim is self.UNSTARTED or self._last_claim < position:
fraction = self.position_to_fraction(
position, start=self._start_position, end=self._stop_position)
self._stop_position = position
return position, fraction
def fraction_consumed(self):
if self._last_claim is self.UNSTARTED:
return 0
else:
return self.position_to_fraction(
self._last_claim, self._start_position, self._stop_position)
def fraction_to_position(self, fraction, start, end):
"""
Converts a fraction between 0 and 1 to a position between start and end.
"""
raise NotImplementedError
def position_to_fraction(self, position, start, end):
"""Returns the fraction of keys in the range [start, end) that
are less than the given key.
"""
raise NotImplementedError
class UnsplittableRangeTracker(iobase.RangeTracker):
"""A RangeTracker that always ignores split requests.
This can be used to make a given
:class:`~apache_beam.io.iobase.RangeTracker` object unsplittable by
ignoring all calls to :meth:`.try_split()`. All other calls will be delegated
to the given :class:`~apache_beam.io.iobase.RangeTracker`.
"""
def __init__(self, range_tracker):
"""Initializes UnsplittableRangeTracker.View on GitHub (pinned to 12126d8942)
Solutions
- Override fraction_to_position(fraction, start, end) in your RangeTracker subclass with a real conversion (e.g. start + fraction*(end-start)).
- If the source cannot support fractional splitting, wrap the tracker in UnsplittableRangeTracker so the method is never called.
- Prefer implementing a RestrictionTracker for splittable DoFns instead of the legacy RangeTracker API.
Example fix
// before
class MyTracker(iobase.RangeTracker):
pass # fraction_to_position not implemented
// after
class MyTracker(iobase.RangeTracker):
def fraction_to_position(self, fraction, start, end):
return int(start + fraction * (end - start)) Defensive patterns
Strategy: fallback
Validate before calling
if type(tracker).fraction_to_position is iobase.RangeTracker.fraction_to_position: tracker = UnsplittableRangeTracker(tracker)
Type guard
def implements_fraction_to_position(tracker) -> bool: return type(tracker).fraction_to_position is not iobase.RangeTracker.fraction_to_position
Try / catch
try: pos = tracker.position_at_fraction(f) except NotImplementedError: pos = None # tracker does not support fractional positioning
Prevention
- Override all abstract methods when subclassing RangeTracker
- Wrap non-splittable trackers in UnsplittableRangeTracker
- Prefer RestrictionTracker for new sources
When it happens
Trigger: Calling position_at_fraction() on a RangeTracker subclass (used by work rebalancing) that inherits from iobase.RangeTracker but does not override fraction_to_position.
Common situations: Implementing a custom RangeTracker for a custom source and forgetting to implement fraction_to_position; enabling dynamic work rebalancing, which then invokes it at runtime.
Understand the failure class
Background: "NotImplementedError: Subclasses should override this method" / "must be implemented" — abstract method errors explained — this error's family across 40 libraries.
Related errors
- Encode not implemented: %s.
- Decode not implemented: %s.
- NotImplementedError
- %s must override get_checkpoint_mark_coder() to return a Cod
- NotImplementedError
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/1b94b4c12164e6da.
Report an issue: GitHub.