{"record":{"id":"c1fb69e3248f2a29","repo":"Lightning-AI/pytorch-lightning","slug":"m-format-on-epoch-on-epoch-fx-name-fx-config","errorCode":null,"errorMessage":"m.format(\"on_epoch\", on_epoch, fx_name, fx_config[\"allowed_on_epoch\"])","messagePattern":"m\\.format\\(\"on_epoch\", on_epoch, fx_name, fx_config\\[\"allowed_on_epoch\"\\]\\)","errorType":"validation","errorClass":"MisconfigurationException","httpStatus":null,"severity":"error","filePath":"src/lightning/pytorch/trainer/connectors/logger_connector/fx_validator.py","lineNumber":189,"sourceCode":"        fx_config = cls.functions[fx_name]\n        assert fx_config is not None\n        on_step = fx_config[\"default_on_step\"] if on_step is None else on_step\n        on_epoch = fx_config[\"default_on_epoch\"] if on_epoch is None else on_epoch\n        return on_step, on_epoch\n\n    @classmethod\n    def check_logging_levels(cls, fx_name: str, on_step: bool, on_epoch: bool) -> None:\n        \"\"\"Check if the logging levels are allowed in the given hook.\"\"\"\n        fx_config = cls.functions[fx_name]\n        assert fx_config is not None\n        m = \"You can't `self.log({}={})` inside `{}`, must be one of {}.\"\n        if on_step not in fx_config[\"allowed_on_step\"]:\n            msg = m.format(\"on_step\", on_step, fx_name, fx_config[\"allowed_on_step\"])\n            raise MisconfigurationException(msg)\n\n        if on_epoch not in fx_config[\"allowed_on_epoch\"]:\n            msg = m.format(\"on_epoch\", on_epoch, fx_name, fx_config[\"allowed_on_epoch\"])\n            raise MisconfigurationException(msg)\n\n    @classmethod\n    def check_logging_and_get_default_levels(\n        cls, fx_name: str, on_step: Optional[bool], on_epoch: Optional[bool]\n    ) -> tuple[bool, bool]:\n        \"\"\"Check if the given hook name is allowed to log and return logging levels.\"\"\"\n        cls.check_logging(fx_name)\n        on_step, on_epoch = cls.get_default_logging_levels(fx_name, on_step, on_epoch)\n        cls.check_logging_levels(fx_name, on_step, on_epoch)\n        return on_step, on_epoch\n","sourceCodeStart":171,"sourceCodeEnd":200,"githubUrl":"https://github.com/Lightning-AI/pytorch-lightning/blob/9fed5c27d2a62ff0efd6c3573599921d6ff67c14/src/lightning/pytorch/trainer/connectors/logger_connector/fx_validator.py#L171-L200","documentation":"Mirror of the on_step check: each hook restricts on_epoch too. When self.log(..., on_epoch=X) passes a value outside fx_config['allowed_on_epoch'] (e.g. on_epoch=True in training_step when only step logging is allowed for that configuration), check_logging_levels raises this MisconfigurationException.","triggerScenarios":"self.log('x', x, on_epoch=True) in a hook whose allowed_on_epoch is False; e.g. certain training_step configurations or custom hooks where epoch aggregation is not supported; any on_epoch value outside the allowed set printed in the message.","commonSituations":"Forcing epoch aggregation for speed-critical training metrics; mixing prog_bar-only step metrics with on_epoch=True in hooks that forbid it; refactoring logging calls between hooks without adjusting flags.","solutions":["Set on_epoch to a value from the message's allowed set, e.g. self.log('x', x, on_step=True, on_epoch=False) in training_step","Drop the explicit flag and let Lightning pick defaults for the hook","Manually aggregate the metric yourself (accumulate in a list, log the mean at epoch end via a callback logger) if you truly need epoch-level values"],"exampleFix":"# before\nself.log('batch_norm_ratio', r, on_step=True, on_epoch=True)  # on_epoch not allowed\n\n# after\nself.log('batch_norm_ratio', r, on_step=True, on_epoch=False)","handlingStrategy":"validation","validationCode":"from lightning.pytorch.trainer.connectors.logger_connector.fx_validator import _FxValidator\ncfg = _FxValidator.functions[hook_name]\nassert on_epoch in cfg[\"allowed_on_epoch\"], f\"allowed: {cfg['allowed_on_epoch']}\"","typeGuard":"def epoch_allowed(hook_name: str, on_epoch: bool) -> bool:\n    from lightning.pytorch.trainer.connectors.logger_connector import fx_validator\n    cfg = fx_validator._FxValidator.functions[hook_name]\n    return cfg is not None and on_epoch in cfg[\"allowed_on_epoch\"]","tryCatchPattern":null,"preventionTips":["Check the error message's allowed set before fixing flags","When moving log calls between hooks, re-validate both flags","Prefer defaults by omitting on_step/on_epoch"],"tags":["pytorch-lightning","logging","on-epoch","misconfiguration"],"backgroundTag":"invalid-logging-level-combination","analyzedSha":"9fed5c27d2a62ff0efd6c3573599921d6ff67c14","analyzedAt":"2026-08-28T11:52:41.083Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}