{"record":{"id":"d01980641774aa5a","repo":"Lightning-AI/pytorch-lightning","slug":"max-epochs-must-be-a-non-negative-integer-or-1","errorCode":null,"errorMessage":"`max_epochs` must be a non-negative integer or -1. You passed in {max_epochs}.","messagePattern":"`max_epochs` must be a non-negative integer or -1\\. You passed in (.+?)\\.","errorType":"exception","errorClass":"MisconfigurationException","httpStatus":null,"severity":"error","filePath":"src/lightning/pytorch/loops/fit_loop.py","lineNumber":96,"sourceCode":"                ...\n            ...\n\n    Args:\n        min_epochs: The minimum number of epochs\n        max_epochs: The maximum number of epochs, can be set -1 to turn this limit off\n\n    \"\"\"\n\n    def __init__(\n        self,\n        trainer: \"pl.Trainer\",\n        min_epochs: Optional[int] = 0,\n        max_epochs: Optional[int] = None,\n    ) -> None:\n        super().__init__(trainer)\n        if isinstance(max_epochs, int) and max_epochs < -1:\n            # Allow max_epochs to be zero, since this will be handled by fit_loop.done\n            raise MisconfigurationException(\n                f\"`max_epochs` must be a non-negative integer or -1. You passed in {max_epochs}.\"\n            )\n\n        self.max_epochs = max_epochs\n        self.min_epochs = min_epochs\n        self.epoch_loop = _TrainingEpochLoop(trainer)\n        self.epoch_progress = _Progress()\n        self.max_batches: Union[int, float] = float(\"inf\")\n\n        self._data_source = _DataLoaderSource(None, \"train_dataloader\")\n        self._combined_loader: Optional[CombinedLoader] = None\n        self._combined_loader_states_to_load: list[dict[str, Any]] = []\n        self._data_fetcher: Optional[_DataFetcher] = None\n        self._last_train_dl_reload_epoch = float(\"-inf\")\n        self._restart_stage = RestartStage.NONE\n\n    @property\n    def total_batch_idx(self) -> int:","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/Lightning-AI/pytorch-lightning/blob/9fed5c27d2a62ff0efd6c3573599921d6ff67c14/src/lightning/pytorch/loops/fit_loop.py#L78-L114","documentation":"Raised by the FitLoop constructor when the `max_epochs` argument passed to `Trainer(max_epochs=...)` is an integer strictly less than -1. Lightning treats -1 as 'infinite epochs' and 0 as a valid value handled later by fit_loop.done, so any value below -1 is rejected as a misconfiguration.","triggerScenarios":"Instantiating `pl.Trainer(max_epochs=-2)` or any more negative int (e.g. -5). Also occurs when max_epochs is computed from config arithmetic that underflows (e.g. `max_epochs=some_value - 3` yielding a negative result).","commonSituations":"Typos or off-by-one math in training scripts; YAML/JSON config files with a negated or misparsed integer; CLI flags parsed as negative numbers; conditional configs like `max_epochs=-1 if resume else epochs` where a bug produces -2 or lower.","solutions":["Set max_epochs to a non-negative integer (e.g. 10) or -1 for infinite training","Check intermediate config values: print/log max_epochs right before Trainer construction to find where it becomes < -1","If parsing from CLI/config, coerce and clamp the value (e.g. `max(max_epochs, -1)` if infinite is intended)"],"exampleFix":"# before\ntrainer = pl.Trainer(max_epochs=n_epochs - 3)  # n_epochs=2 -> -1 ok, but n_epochs=1 -> -2 raises\n\n# after\ntrainer = pl.Trainer(max_epochs=max(n_epochs - 3, 1))","handlingStrategy":"validation","validationCode":"def safe_max_epochs(v):\n    if isinstance(v, int) and v < -1:\n        raise ValueError(f\"max_epochs must be >= -1, got {v}\")\n    return v\n\ntrainer = pl.Trainer(max_epochs=safe_max_epochs(cfg['max_epochs']))","typeGuard":"def is_valid_max_epochs(v) -> bool:\n    return not isinstance(v, int) or v >= -1","tryCatchPattern":null,"preventionTips":["Validate integer hyperparameters in config loading (pydantic/jsonschema) before constructing the Trainer","Clamp sentinel arithmetic: max(max_epochs, -1) when -1 means infinite","Log the final Trainer kwargs at startup for auditability"],"tags":["pytorch-lightning","trainer","max-epochs","configuration","validation"],"backgroundTag":"invalid-training-hyperparameter","analyzedSha":"9fed5c27d2a62ff0efd6c3573599921d6ff67c14","analyzedAt":"2026-08-28T11:52:41.083Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}