apache/beam · error · NotImplementedError

NotImplementedError(type(self))

Error message

NotImplementedError(type(self))

What it means

The base DistributionCell-family (cell subclass in cells.py) implements update() by delegating to _update_locked, whose stub raises NotImplementedError with the concrete class name. Any subclass that does not override _update_locked cannot accept values.

Source

Thrown at sdks/python/apache_beam/metrics/cells.py:253

  def reset(self):
    self.data = self.data_class.identity_element()

  def combine(self, other: 'AbstractMetricCell') -> 'AbstractMetricCell':
    result = type(self)()  # type: ignore[call-arg]
    result.data = self.data.combine(other.data)
    return result

  def set(self, value):
    with self._lock:
      self._update_locked(value)

  def update(self, value):
    with self._lock:
      self._update_locked(value)

  def _update_locked(self, value):
    raise NotImplementedError(type(self))

  def get_cumulative(self):
    with self._lock:
      return self.data.get_cumulative()

  def to_runner_api_monitoring_info_impl(self, name, transform_id):
    raise NotImplementedError(type(self))


class GaugeCell(AbstractMetricCell):
  """For internal use only; no backwards-compatibility guarantees.

  Tracks the current value and delta for a gauge metric.

  Each cell tracks the state of a metric independently per context per bundle.
  Therefore, each metric has a different cell in each bundle, that is later
  aggregated.

View on GitHub (pinned to 12126d8942)

Solutions

  1. Implement _update_locked(self, value) in your subclass to record the value under the held lock (it is called with self._lock already acquired).
  2. Prefer subclassing an existing concrete cell (CounterCell, DistributionCell, StringSetCell) rather than the base.
  3. Check the NotImplementedError message: it names type(self), telling you exactly which class lacks the method.

Example fix

class MyCell(MetricCell):
-  # _update_locked not implemented
+  def _update_locked(self, value):
+    self.data += value
Defensive patterns

Strategy: type-guard

Validate before calling

assert type(cell)._update_locked is not MetricCell._update_locked, 'subclass must implement _update_locked'

Type guard

def is_updatable_cell(cell):
    return type(cell)._update_locked is not MetricCell._update_locked

Try / catch

try:
    cell.update(value)
except NotImplementedError as e:
    raise TypeError(f'{e.args[0]} does not support update')

Prevention

When it happens

Trigger: Calling set(value) or update(value) on a custom MetricCell subclass that implements to_runner_api_monitoring_info_impl but not _update_locked.

Common situations: Incomplete custom metric cell implementations where update was assumed optional; Beam internals dispatching update after the cell reached a runner stage with an abstract cell type.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/8b4e9eddeeecda7c. Report an issue: GitHub.