Lightning-AI/pytorch-lightning · error · MisconfigurationException

logging_interval should be `step` or `epoch` or `None`.

Error message

logging_interval should be `step` or `epoch` or `None`.

What it means

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.

Source

Thrown at src/lightning/pytorch/callbacks/lr_monitor.py:106

                    'params': [p for p in self.parameters()],
                    'name': 'my_parameter_group_name'
                }],
                lr=0.1
            )
            lr_scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer, ...)
            return [optimizer], [lr_scheduler]

    """

    def __init__(
        self,
        logging_interval: Optional[Literal["step", "epoch"]] = None,
        log_momentum: bool = False,
        log_weight_decay: bool = False,
        log_key_prefix: Optional[str] = None,
    ) -> None:
        if logging_interval not in (None, "step", "epoch"):
            raise MisconfigurationException("logging_interval should be `step` or `epoch` or `None`.")

        self.logging_interval = logging_interval
        self.log_momentum = log_momentum
        self.log_weight_decay = log_weight_decay
        self.log_key_prefix = log_key_prefix or ""

        self.lrs: dict[str, list[float]] = {}
        self.last_momentum_values: dict[str, Optional[list[float]]] = {}
        self.last_weight_decay_values: dict[str, Optional[list[float]]] = {}

    @override
    def on_train_start(self, trainer: "pl.Trainer", *args: Any, **kwargs: Any) -> None:
        """Called before training, determines unique names for all lr schedulers in the case of multiple of the same
        type or in the case of multiple parameter groups.

        Raises:
            MisconfigurationException:
                If ``Trainer`` has no ``logger``.

View on GitHub (pinned to 9fed5c27d2)

Solutions

  1. Use `logging_interval='epoch'` or `'step'`, or omit it (None) to get both
  2. Normalize config input: strip whitespace and lowercase before passing
  3. Check for exact string equality — values are not fuzzy matched

Example fix

# before
LearningRateMonitor(logging_interval='batch')
# after
LearningRateMonitor(logging_interval='step')
Defensive patterns

Strategy: type-guard

Validate before calling

if logging_interval is not None:
    logging_interval = logging_interval.strip().lower()
assert logging_interval in (None, 'step', 'epoch')

Type guard

from typing import Literal
LrInterval = Literal['step', 'epoch', None]
def is_valid_interval(v) -> bool:
    return v is None or (isinstance(v, str) and v in ('step', 'epoch'))

Prevention

When it happens

Trigger: `LearningRateMonitor(logging_interval='batch')`, `'steps'`, `'Epoch'`, or `'none'`. Constructing the monitor with such a value fails immediately.

Common situations: Intuitive but wrong words like 'batch'/'iteration'; pluralized 'epochs'; casing or quoting mistakes in YAML configs.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of Lightning-AI/pytorch-lightning@9fed5c27d2 (2026-08-28). Data as JSON: /api/errors/3541262cf12e4569. Report an issue: GitHub.