{"record":{"id":"e9f6622d37cd77df","repo":"keras-team/keras","slug":"layer-add-metric-method-is-deprecated-add-you","errorCode":null,"errorMessage":"Layer `add_metric()` method is deprecated. Add your metric in `Model.compile(metrics=[...])`, or create metric trackers in init() or build() when subclassing the layer or model, then call `metric.update_state()` whenever necessary.","messagePattern":"Layer `add_metric\\(\\)` method is deprecated\\. Add your metric in `Model\\.compile\\(metrics=\\[\\.\\.\\.\\]\\)`, or create metric trackers in init\\(\\) or build\\(\\) when subclassing the layer or model, then call `metric\\.update_state\\(\\)` whenever necessary\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"keras/src/layers/layer.py","lineNumber":1540,"sourceCode":"        if variable.trainable:\n            self._tracker.add_to_store(\"trainable_variables\", variable)\n        else:\n            self._tracker.add_to_store(\"non_trainable_variables\", variable)\n        if not self.trainable:\n            variable.trainable = False\n        self._post_track_variable(variable)\n\n    def _untrack_variable(self, variable):\n        previous_lock_state = self._tracker.locked\n        self._tracker.unlock()\n        self._tracker.untrack(variable)\n        if previous_lock_state is True:\n            self._tracker.lock()\n        self._post_untrack_variable(variable)\n\n    def add_metric(self, *args, **kwargs):\n        # Permanently disabled\n        raise NotImplementedError(\n            \"Layer `add_metric()` method is deprecated. \"\n            \"Add your metric in `Model.compile(metrics=[...])`, \"\n            \"or create metric trackers in init() or build() \"\n            \"when subclassing the layer or model, then call \"\n            \"`metric.update_state()` whenever necessary.\"\n        )\n\n    def count_params(self):\n        \"\"\"Count the total number of scalars composing the weights.\n\n        Returns:\n            An integer count.\n        \"\"\"\n        if not self.built:\n            raise ValueError(\n                \"You tried to call `count_params` \"\n                f\"on layer '{self.name}', \"\n                \"but the layer isn't built. \"","sourceCodeStart":1522,"sourceCodeEnd":1558,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/layers/layer.py#L1522-L1558","documentation":"Keras 3 permanently removed Layer.add_metric(). Calling it always raises NotImplementedError with guidance: track metrics via Model.compile(metrics=[...]) or create metric tracker objects (e.g. keras.metrics.Mean) in __init__/build and call update_state() in call().","triggerScenarios":"Any call to self.add_metric(value, name=...) in subclassed layers ported from Keras 2 or TF2.","commonSituations":"Migrating Keras 2 custom layers and models to Keras 3; old tutorials using add_metric inside call().","solutions":["Create metric objects in __init__ (self.mae_metric = keras.metrics.MeanAbsoluteError(name='mae')) and call self.mae_metric.update_state(y, y_pred) in call/train_step","Track metrics via Model.compile(metrics=[...]) where possible","Delete all add_metric call sites when porting"],"exampleFix":"# before\ndef call(self, x):\n    self.add_loss(self.reg_loss(x))\n    self.add_metric(self.reg_loss(x), name='reg')\n# after\ndef __init__(self, **kw):\n    super().__init__(**kw)\n    self.reg_metric = keras.metrics.Mean(name='reg')\ndef call(self, x):\n    self.reg_metric.update_state(self.reg_loss(x))\n    return x","handlingStrategy":"validation","validationCode":"# static migration: grep for add_metric and replace with metric trackers","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Search codebases for add_metric when upgrading to Keras 3","Create keras.metrics.* trackers in __init__ and call update_state in call/train_step"],"tags":["keras","metrics","deprecated-api","migration"],"backgroundTag":"removed-api-usage","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}