{"record":{"id":"4d605ffc6fe32239","repo":"Lightning-AI/pytorch-lightning","slug":"val-check-interval-trainer-val-check-interval","errorCode":null,"errorMessage":" `val_check_interval` ({trainer.val_check_interval}) must be less than or equal to the number of the training batches ({self.max_batches}). If you want to disable validation set `limit_val_batches` to 0.0 instead. If you want to validate based on the total training batches, set `check_val_every_n_epoch=None`.","messagePattern":" `val_check_interval` \\((.+?)\\) must be less than or equal to the number of the training batches \\((.+?)\\)\\. If you want to disable validation set `limit_val_batches` to 0\\.0 instead\\. If you want to validate based on the total training batches, set `check_val_every_n_epoch=None`\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/lightning/pytorch/loops/fit_loop.py","lineNumber":300,"sourceCode":"            return\n\n        # store epoch of dataloader reset for reload_dataloaders_every_n_epochs\n        self._last_train_dl_reload_epoch = trainer.current_epoch\n\n        # If time-based validation is enabled, disable batch-based scheduling here.\n        # Use None to clearly signal \"no batch-based validation\"; wall-time logic will run elsewhere.\n        if getattr(trainer, \"_val_check_time_interval\", None) is not None:\n            trainer.val_check_batch = None\n            trainer._train_start_time = time.monotonic()\n            trainer._last_val_time = trainer._train_start_time\n        elif isinstance(trainer.val_check_interval, int):\n            trainer.val_check_batch = trainer.val_check_interval\n            if (\n                trainer.val_check_batch > self.max_batches\n                and trainer.check_val_every_n_epoch is not None\n                and trainer.limit_val_batches > 0\n            ):\n                raise ValueError(\n                    f\" `val_check_interval` ({trainer.val_check_interval}) must be less than or equal\"\n                    f\" to the number of the training batches ({self.max_batches}).\"\n                    \" If you want to disable validation set `limit_val_batches` to 0.0 instead.\"\n                    \" If you want to validate based on the total training batches, set `check_val_every_n_epoch=None`.\"\n                )\n        else:\n            if not has_len_all_ranks_:\n                if trainer.val_check_interval == 1.0:\n                    trainer.val_check_batch = float(\"inf\")\n                else:\n                    raise MisconfigurationException(\n                        \"When using an IterableDataset for `train_dataloader`,\"\n                        \" `Trainer(val_check_interval)` must be time based, `1.0` or an int. An int k specifies\"\n                        \" checking validation every k training batches.\"\n                    )\n            else:\n                trainer.val_check_batch = int(self.max_batches * trainer.val_check_interval)\n                trainer.val_check_batch = max(1, trainer.val_check_batch)","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/Lightning-AI/pytorch-lightning/blob/9fed5c27d2a62ff0efd6c3573599921d6ff67c14/src/lightning/pytorch/loops/fit_loop.py#L282-L318","documentation":"Raised in FitLoop.setup_data when an integer `val_check_interval` exceeds the total number of training batches in the epoch while validation is actually enabled (check_val_every_n_epoch is not None and limit_val_batches > 0). Lightning cannot schedule a validation check after more batches than exist, so it refuses rather than silently never validating.","triggerScenarios":"Setting `Trainer(val_check_interval=1000)` when the training dataloader yields fewer than 1000 batches per epoch; or a fractional val_check_interval times max_batches rounds down to 0 forcing a batch-based interval larger than the epoch; small datasets combined with large int val_check_interval values.","commonSituations":"Copying a Trainer config from a large-dataset experiment to a small smoke-test dataset; limiting train batches via limit_train_batches so the effective batch count drops below val_check_interval; changing batch size upward so fewer steps per epoch remain.","solutions":["Reduce val_check_interval to be <= number of training batches (commonly 1.0 or a small int)","If validation should not run, set `limit_val_batches=0.0`","If you want the interval interpreted against total training batches across epochs, set `check_val_every_n_epoch=None`","Increase available training batches by raising limit_train_batches or lowering batch size"],"exampleFix":"# before\ntrainer = pl.Trainer(val_check_interval=5000)  # epoch only has 100 batches\n\n# after\ntrainer = pl.Trainer(val_check_interval=100)  # or 1.0 to validate once per epoch","handlingStrategy":"validation","validationCode":"n_batches = len(train_dataloader) // trainer_config.get('limit_train_batches_len', 1.0)\nvci = trainer_config['val_check_interval']\nif isinstance(vci, int) and vci > n_batches:\n    vci = max(1, n_batches)  # or 1.0\ntrainer = pl.Trainer(val_check_interval=vci)","typeGuard":"def interval_ok(vci: int, n_batches: int) -> bool:\n    return vci <= n_batches","tryCatchPattern":null,"preventionTips":["Derive val_check_interval from the dataloader length instead of hardcoding","When running smoke tests with limit_train_batches, scale val_check_interval down too","Prefer fractional 1.0 or small ints unless batch-count precision is needed"],"tags":["pytorch-lightning","validation","val-check-interval","scheduling"],"backgroundTag":"config-value-out-of-range","analyzedSha":"9fed5c27d2a62ff0efd6c3573599921d6ff67c14","analyzedAt":"2026-08-28T11:52:41.083Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}