{"record":{"id":"8b4e9eddeeecda7c","repo":"apache/beam","slug":"notimplementederror-type-self","errorCode":null,"errorMessage":"NotImplementedError(type(self))","messagePattern":"NotImplementedError\\(type\\(self\\)\\)","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/metrics/cells.py","lineNumber":253,"sourceCode":"\n  def reset(self):\n    self.data = self.data_class.identity_element()\n\n  def combine(self, other: 'AbstractMetricCell') -> 'AbstractMetricCell':\n    result = type(self)()  # type: ignore[call-arg]\n    result.data = self.data.combine(other.data)\n    return result\n\n  def set(self, value):\n    with self._lock:\n      self._update_locked(value)\n\n  def update(self, value):\n    with self._lock:\n      self._update_locked(value)\n\n  def _update_locked(self, value):\n    raise NotImplementedError(type(self))\n\n  def get_cumulative(self):\n    with self._lock:\n      return self.data.get_cumulative()\n\n  def to_runner_api_monitoring_info_impl(self, name, transform_id):\n    raise NotImplementedError(type(self))\n\n\nclass GaugeCell(AbstractMetricCell):\n  \"\"\"For internal use only; no backwards-compatibility guarantees.\n\n  Tracks the current value and delta for a gauge metric.\n\n  Each cell tracks the state of a metric independently per context per bundle.\n  Therefore, each metric has a different cell in each bundle, that is later\n  aggregated.\n","sourceCodeStart":235,"sourceCodeEnd":271,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/metrics/cells.py#L235-L271","documentation":"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.","triggerScenarios":"Calling set(value) or update(value) on a custom MetricCell subclass that implements to_runner_api_monitoring_info_impl but not _update_locked.","commonSituations":"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.","solutions":["Implement _update_locked(self, value) in your subclass to record the value under the held lock (it is called with self._lock already acquired).","Prefer subclassing an existing concrete cell (CounterCell, DistributionCell, StringSetCell) rather than the base.","Check the NotImplementedError message: it names type(self), telling you exactly which class lacks the method."],"exampleFix":"class MyCell(MetricCell):\n-  # _update_locked not implemented\n+  def _update_locked(self, value):\n+    self.data += value","handlingStrategy":"type-guard","validationCode":"assert type(cell)._update_locked is not MetricCell._update_locked, 'subclass must implement _update_locked'","typeGuard":"def is_updatable_cell(cell):\n    return type(cell)._update_locked is not MetricCell._update_locked","tryCatchPattern":"try:\n    cell.update(value)\nexcept NotImplementedError as e:\n    raise TypeError(f'{e.args[0]} does not support update')","preventionTips":["Implement _update_locked (called under self._lock) in every custom cell.","Prefer subclassing CounterCell/DistributionCell over the abstract base.","Check the NotImplementedError message, which names the offending class."],"tags":["python","apache-beam","metrics","abstract-method"],"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-14T16:17:12.679Z"}