{"record":{"id":"7ab2b0ba19d219bf","repo":"apache/beam","slug":"should-only-be-called-on-sub-trackers","errorCode":null,"errorMessage":"Should only be called on sub-trackers","messagePattern":"Should only be called on sub-trackers","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/concat_source.py","lineNumber":214,"sourceCode":"          # Prefer to split on even boundary.\n          split_pos = None\n          ratio = self._cumulative_weights[source_ix]\n        else:\n          # Split the current subsource.\n          split = self.sub_range_tracker(source_ix).try_split(source_pos)\n          if not split:\n            return None\n          split_pos, frac = split\n          ratio = self.local_to_global(source_ix, frac)\n\n        self._end = source_ix, split_pos\n        self._cumulative_weights = [\n            min(w / ratio, 1) for w in self._cumulative_weights\n        ]\n        return (source_ix, split_pos), ratio\n\n  def set_current_position(self, pos):\n    raise NotImplementedError('Should only be called on sub-trackers')\n\n  def position_at_fraction(self, fraction):\n    source_ix, source_frac = self.global_to_local(fraction)\n    last = self._end[0] if self._end[1] is None else self._end[0] + 1\n    if source_ix == last:\n      return (source_ix, None)\n    else:\n      return (\n          source_ix,\n          self.sub_range_tracker(source_ix).position_at_fraction(source_frac))\n\n  def fraction_consumed(self):\n    with self._lock:\n      if self._claimed_source_ix == len(self._source_bundles):\n        return 1.0\n      else:\n        return self.local_to_global(\n            self._claimed_source_ix,","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/concat_source.py#L196-L232","documentation":"_ConcatSourceProgressTracker represents progress across multiple sub-sources; individual position tracking must be done by each sub-tracker. set_current_position() is intentionally unimplemented on the composite tracker and always raises NotImplementedError('Should only be called on sub-trackers').","triggerScenarios":"Calling set_current_position(pos) on the ConcatSource-level progress tracker (obtained from a ConcatSource reader) instead of on a sub-source tracker; custom runner code that drives progress generically.","commonSituations":"Custom runners/dynamic work rebalancing that assume every tracker supports set_current_position; unit tests exercising composite source progress directly.","solutions":["Route set_current_position calls to the appropriate sub-tracker for the current source index","Use position_at_fraction()/fraction-based APIs on the composite tracker instead","Update runner integration to handle composite trackers specially"],"exampleFix":"// before\nreader.get_progress().set_current_position(pos)\n// after\nsub_tracker = tracker.trackers[current_source_index]\nsub_tracker.set_current_position(local_pos)","handlingStrategy":"validation","validationCode":"from apache_beam.io.concat_source import _ConcatSourceProgressTracker\nif isinstance(tracker, _ConcatSourceProgressTracker):\n    raise TypeError('use sub-trackers for set_current_position')","typeGuard":"def is_sub_tracker(tracker):\n    return not hasattr(tracker, '_source_bundles')","tryCatchPattern":"try:\n    tracker.set_current_position(pos)\nexcept NotImplementedError:\n    sub = tracker.get_sub_trackers()[current_index]\n    sub.set_current_position(local_pos)","preventionTips":["Detect composite trackers via isinstance before calling set_current_position","Prefer fraction-based progress APIs on composite sources","Keep runner progress code aware of source composition"],"tags":["beam","progress-tracking","not-implemented"],"backgroundTag":"method-not-implemented","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"}