Lightning-AI/pytorch-lightning · error · MisconfigurationException
`max_steps` must be a non-negative integer or -1 (infinite s
Error message
`max_steps` must be a non-negative integer or -1 (infinite steps). You passed in {max_steps}. What it means
Raised by _TrainingEpochLoop.__init__ when the max_steps argument is an int strictly less than -1. -1 means 'unlimited steps' (the default) and 0 is allowed, so anything below -1 is treated as an invalid hyperparameter.
Source
Thrown at src/lightning/pytorch/loops/training_epoch_loop.py:76
The validation is carried out by yet another loop,
:class:`~lightning.pytorch.loops._EvaluationLoop`.
In the ``run()`` method, the training epoch loop could in theory simply call the
``LightningModule.training_step`` already and perform the optimization.
However, Lightning has built-in support for automatic optimization with multiple optimizers.
For this reason there are actually two more loops nested under
:class:`~lightning.pytorch.loops._TrainingEpochLoop`.
Args:
min_steps: The minimum number of steps (batches) to process
max_steps: The maximum number of steps (batches) to process
"""
def __init__(self, trainer: "pl.Trainer", min_steps: Optional[int] = None, max_steps: int = -1) -> None:
super().__init__(trainer)
if max_steps < -1:
raise MisconfigurationException(
f"`max_steps` must be a non-negative integer or -1 (infinite steps). You passed in {max_steps}."
)
self.min_steps = min_steps
self.max_steps = max_steps
self.batch_progress = _BatchProgress()
self.scheduler_progress = _SchedulerProgress()
self.automatic_optimization = _AutomaticOptimization(trainer)
self.manual_optimization = _ManualOptimization(trainer)
self.val_loop = loops._EvaluationLoop(
trainer, TrainerFn.FITTING, RunningStage.VALIDATING, verbose=False, inference_mode=False
)
self._results = _ResultCollection(training=True)
self._warning_cache = WarningCache()
self._batches_that_stepped: int = 0View on GitHub (pinned to 9fed5c27d2)
Solutions
- Set max_steps to a non-negative int or -1 (infinite)
- Clamp computed values: `max_steps = max(max_steps, -1)`
- Log/inspect the computed max_steps before constructing the Trainer
Example fix
# before trainer = pl.Trainer(max_steps=steps_left - 10) # can be -2 # after trainer = pl.Trainer(max_steps=max(steps_left - 10, -1))
Defensive patterns
Strategy: validation
Validate before calling
max_steps = max(cfg['max_steps'], -1) if isinstance(cfg['max_steps'], int) else -1 trainer = pl.Trainer(max_steps=max_steps)
Type guard
def valid_max_steps(v) -> bool:
return isinstance(v, int) and v >= -1 Prevention
- Validate computed step budgets against the -1 sentinel before Trainer construction
- Log effective Trainer hyperparameters when resuming from checkpoints
When it happens
Trigger: Setting `Trainer(max_steps=-2)`; deriving max_steps from arithmetic like `max_steps=remaining_steps - overhang` that goes below -1; config files with negative step budgets.
Common situations: Resume-from-checkpoint logic computing remaining steps incorrectly; CLI misparsing; copying max_epochs-style -1 sentinel conventions while also subtracting values.
Related errors
- Device should be CUDA, got {device} instead.
- You requested to find {num_devices} devices but there are no
- `max_epochs` must be a non-negative integer or -1. You passe
- No `{step_name}()` method defined to run `Trainer.{trainer_m
- You requested to find {num_devices} devices but this machine
AI-assisted analysis of Lightning-AI/pytorch-lightning@9fed5c27d2 (2026-08-28).
Data as JSON: /api/errors/1362aea7b577f63c.
Report an issue: GitHub.