{"record":{"id":"47cd0cbcacf66311","repo":"apache/beam","slug":"initialize-threadsaferestrictiontracker","errorCode":null,"errorMessage":"Initialize ThreadsafeRestrictionTracker requiresRestrictionTracker.","messagePattern":"Initialize ThreadsafeRestrictionTracker requiresRestrictionTracker\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/runners/sdf_utils.py","lineNumber":60,"sourceCode":"SplitResultPrimary = NamedTuple(\n    'SplitResultPrimary', [('primary_value', WindowedValue)])\n\nSplitResultResidual = NamedTuple(\n    'SplitResultResidual',\n    [('residual_value', WindowedValue), ('current_watermark', Timestamp),\n     ('deferred_timestamp', Optional[Duration])])\n\n\nclass ThreadsafeRestrictionTracker(object):\n  \"\"\"A thread-safe wrapper which wraps a `RestrictionTracker`.\n\n  This wrapper guarantees synchronization of modifying restrictions across\n  multi-thread.\n  \"\"\"\n  def __init__(self, restriction_tracker: 'RestrictionTracker') -> None:\n    from apache_beam.io.iobase import RestrictionTracker\n    if not isinstance(restriction_tracker, RestrictionTracker):\n      raise ValueError(\n          'Initialize ThreadsafeRestrictionTracker requires'\n          'RestrictionTracker.')\n    self._restriction_tracker = restriction_tracker\n    # Records an absolute timestamp when defer_remainder is called.\n    self._timestamp = None\n    self._lock = threading.RLock()\n    self._deferred_residual = None\n    self._deferred_timestamp: Optional[Union[Timestamp, Duration]] = None\n\n  def current_restriction(self):\n    with self._lock:\n      return self._restriction_tracker.current_restriction()\n\n  def try_claim(self, position):\n    with self._lock:\n      return self._restriction_tracker.try_claim(position)\n\n  def defer_remainder(self, deferred_time=None):","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/runners/sdf_utils.py#L42-L78","documentation":"ThreadsafeRestrictionTracker wraps a RestrictionTracker to make it thread-safe for splittable DoFn use. Its constructor type-checks the argument and raises this ValueError if the object is not an instance of apache_beam.io.iobase.RestrictionTracker.","triggerScenarios":"Instantiating ThreadsafeRestrictionTracker(x) where x is None, a raw restriction, a custom tracker not subclassing RestrictionTracker, or an object from a different tracker hierarchy.","commonSituations":"Writing a custom splittable DoFn and passing the restriction instead of the tracker; a custom tracker class that forgets to inherit from RestrictionTracker.","solutions":["Pass a valid RestrictionTracker instance (e.g. OffsetRangeTracker) into ThreadsafeRestrictionTracker","Make your custom tracker subclass apache_beam.io.iobase.RestrictionTracker","Check that you are not passing None or the restriction object itself"],"exampleFix":"// before\ntracker = ThreadsafeRestrictionTracker(OffsetRange(0, 100))\n// after\nfrom apache_beam.io.iobase import RestrictionTracker\nfrom apache_beam.io.restriction_trackers import OffsetRangeTracker\ntracker = ThreadsafeRestrictionTracker(OffsetRangeTracker(OffsetRange(0, 100)))","handlingStrategy":"type-guard","validationCode":"from apache_beam.io.iobase import RestrictionTracker\nisinstance(x, RestrictionTracker)  # check before constructing","typeGuard":"from apache_beam.io.iobase import RestrictionTracker\ndef is_restriction_tracker(x) -> bool:\n    return isinstance(x, RestrictionTracker)","tryCatchPattern":"try:\n    tracker = ThreadsafeRestrictionTracker(x)\nexcept ValueError as e:\n    if 'RestrictionTracker' in str(e):\n        raise TypeError('must pass a RestrictionTracker') from e\n    raise","preventionTips":["Always wrap restrictions in a tracker (e.g. OffsetRangeTracker) first","Subclass RestrictionTracker for custom trackers","Add isinstance asserts in custom DoFn constructors"],"tags":["apache-beam","sdf","type-mismatch","restriction-tracker"],"backgroundTag":"invalid-constructor-argument","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"}