Lightning-AI/pytorch-lightning · critical · MisconfigurationException
The lr scheduler dict must have the key "scheduler" with its
Error message
The lr scheduler dict must have the key "scheduler" with its item being an lr scheduler
What it means
When a learning-rate scheduler is provided as a dict in configure_optimizers output, the dict must contain the key "scheduler" mapping to the scheduler object. After unsupported keys are stripped (with a warning), a missing "scheduler" key raises MisconfigurationException.
Source
Thrown at src/lightning/pytorch/core/optimizer.py:266
def _configure_schedulers_automatic_opt(schedulers: list, monitor: Optional[str]) -> list[LRSchedulerConfig]:
"""Convert each scheduler into `LRSchedulerConfig` with relevant information, when using automatic optimization."""
lr_scheduler_configs = []
for scheduler in schedulers:
if isinstance(scheduler, dict):
# check provided keys
supported_keys = {field.name for field in fields(LRSchedulerConfig)}
extra_keys = scheduler.keys() - supported_keys
if extra_keys:
rank_zero_warn(
f"Found unsupported keys in the lr scheduler dict: {extra_keys}."
" HINT: remove them from the output of `configure_optimizers`.",
category=RuntimeWarning,
)
scheduler = {k: v for k, v in scheduler.items() if k in supported_keys}
if "scheduler" not in scheduler:
raise MisconfigurationException(
'The lr scheduler dict must have the key "scheduler" with its item being an lr scheduler'
)
if "interval" in scheduler and scheduler["interval"] not in ("step", "epoch"):
raise MisconfigurationException(
'The "interval" key in lr scheduler dict must be "step" or "epoch"'
f' but is "{scheduler["interval"]}"'
)
scheduler["reduce_on_plateau"] = scheduler.get(
"reduce_on_plateau", isinstance(scheduler["scheduler"], optim.lr_scheduler.ReduceLROnPlateau)
)
if scheduler["reduce_on_plateau"] and scheduler.get("monitor") is None:
raise MisconfigurationException(
"The lr scheduler dict must include a monitor when a `ReduceLROnPlateau` scheduler is used."
' For example: {"optimizer": optimizer, "lr_scheduler":'
' {"scheduler": scheduler, "monitor": "your_loss"}}'
)
is_one_cycle = isinstance(scheduler["scheduler"], optim.lr_scheduler.OneCycleLR)
if is_one_cycle and scheduler.get("interval", "epoch") == "epoch":View on GitHub (pinned to 9fed5c27d2)
Solutions
- Use the key 'scheduler': {'optimizer': opt, 'lr_scheduler': {'scheduler': sched, 'monitor': 'val_loss'}}
- Or simply return the bare scheduler object and let Lightning wrap it: return opt, sched
Example fix
# before
return {'optimizer': opt, 'lr_scheduler': {'lr_scheduler': sched, 'monitor': 'val_loss'}}
# after
return {'optimizer': opt, 'lr_scheduler': {'scheduler': sched, 'monitor': 'val_loss'}} Defensive patterns
Strategy: validation
Validate before calling
for s in schedulers:
if isinstance(s, dict):
assert "scheduler" in s, 'scheduler dict needs key "scheduler"' Type guard
def is_valid_sched_dict(d: dict) -> bool:
return isinstance(d, dict) and "scheduler" in d Prevention
- Return bare scheduler objects where possible so Lightning builds the dict
- Keep scheduler dict construction in one helper to avoid key typos
When it happens
Trigger: Returning {'lr_scheduler': sched, 'monitor': 'val_loss'} — nesting under 'lr_scheduler' instead of using the key 'scheduler' inside the scheduler dict.
Common situations: Confusion between the top-level configure_optimizers dict (key 'lr_scheduler') and the per-scheduler dict (key 'scheduler'); renaming or hand-writing the dict and omitting the key.
Related errors
- Unknown configuration for model optimizers. Output from `mod
- The "interval" key in lr scheduler dict must be "step" or "e
- Some schedulers are attached with an optimizer that wasn't r
- {seed} is not in bounds, numpy accepts from {min_seed_value}
- Expected samples ({samples}) to be greater or equal than bat
AI-assisted analysis of Lightning-AI/pytorch-lightning@9fed5c27d2 (2026-08-28).
Data as JSON: /api/errors/b9e9bec3089fbbba.
Report an issue: GitHub.