{"record":{"id":"3541262cf12e4569","repo":"Lightning-AI/pytorch-lightning","slug":"logging-interval-should-be-step-or-epoch-or-n","errorCode":null,"errorMessage":"logging_interval should be `step` or `epoch` or `None`.","messagePattern":"logging_interval should be `step` or `epoch` or `None`\\.","errorType":"validation","errorClass":"MisconfigurationException","httpStatus":null,"severity":"error","filePath":"src/lightning/pytorch/callbacks/lr_monitor.py","lineNumber":106,"sourceCode":"                    'params': [p for p in self.parameters()],\n                    'name': 'my_parameter_group_name'\n                }],\n                lr=0.1\n            )\n            lr_scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer, ...)\n            return [optimizer], [lr_scheduler]\n\n    \"\"\"\n\n    def __init__(\n        self,\n        logging_interval: Optional[Literal[\"step\", \"epoch\"]] = None,\n        log_momentum: bool = False,\n        log_weight_decay: bool = False,\n        log_key_prefix: Optional[str] = None,\n    ) -> None:\n        if logging_interval not in (None, \"step\", \"epoch\"):\n            raise MisconfigurationException(\"logging_interval should be `step` or `epoch` or `None`.\")\n\n        self.logging_interval = logging_interval\n        self.log_momentum = log_momentum\n        self.log_weight_decay = log_weight_decay\n        self.log_key_prefix = log_key_prefix or \"\"\n\n        self.lrs: dict[str, list[float]] = {}\n        self.last_momentum_values: dict[str, Optional[list[float]]] = {}\n        self.last_weight_decay_values: dict[str, Optional[list[float]]] = {}\n\n    @override\n    def on_train_start(self, trainer: \"pl.Trainer\", *args: Any, **kwargs: Any) -> None:\n        \"\"\"Called before training, determines unique names for all lr schedulers in the case of multiple of the same\n        type or in the case of multiple parameter groups.\n\n        Raises:\n            MisconfigurationException:\n                If ``Trainer`` has no ``logger``.","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/Lightning-AI/pytorch-lightning/blob/9fed5c27d2a62ff0efd6c3573599921d6ff67c14/src/lightning/pytorch/callbacks/lr_monitor.py#L88-L124","documentation":"LearningRateMonitor only logs at per-step or per-epoch granularity. Its `__init__` validates that `logging_interval` is None (both), 'step', or 'epoch', and raises MisconfigurationException for anything else, before the Trainer is even constructed with the callback.","triggerScenarios":"`LearningRateMonitor(logging_interval='batch')`, `'steps'`, `'Epoch'`, or `'none'`. Constructing the monitor with such a value fails immediately.","commonSituations":"Intuitive but wrong words like 'batch'/'iteration'; pluralized 'epochs'; casing or quoting mistakes in YAML configs.","solutions":["Use `logging_interval='epoch'` or `'step'`, or omit it (None) to get both","Normalize config input: strip whitespace and lowercase before passing","Check for exact string equality — values are not fuzzy matched"],"exampleFix":"# before\nLearningRateMonitor(logging_interval='batch')\n# after\nLearningRateMonitor(logging_interval='step')","handlingStrategy":"type-guard","validationCode":"if logging_interval is not None:\n    logging_interval = logging_interval.strip().lower()\nassert logging_interval in (None, 'step', 'epoch')","typeGuard":"from typing import Literal\nLrInterval = Literal['step', 'epoch', None]\ndef is_valid_interval(v) -> bool:\n    return v is None or (isinstance(v, str) and v in ('step', 'epoch'))","tryCatchPattern":null,"preventionTips":["Type the config field as Literal['step','epoch']","Use 'step'/'epoch' exactly — no plurals or 'batch'"],"tags":["lightning","lr-monitor","invalid-argument","callback-config"],"backgroundTag":"invalid-config-value","analyzedSha":"9fed5c27d2a62ff0efd6c3573599921d6ff67c14","analyzedAt":"2026-08-28T11:52:41.083Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}