{"record":{"id":"f205147a65e34310","repo":"Lightning-AI/pytorch-lightning","slug":"train-dataloader-yielded-none-if-this-was-on-purp","errorCode":null,"errorMessage":"train_dataloader yielded None. If this was on purpose, ignore this warning...","messagePattern":"train_dataloader yielded None\\. If this was on purpose, ignore this warning\\.\\.\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/lightning/pytorch/loops/training_epoch_loop.py","lineNumber":331,"sourceCode":"            # fetcher state so that the batch_idx is correct after restarting\n            batch_idx = self.batch_idx + 1\n        # Note: `is_last_batch` is not yet determined if data fetcher is a `_DataLoaderIterDataFetcher`\n        self.batch_progress.is_last_batch = data_fetcher.done\n\n        trainer = self.trainer\n        if not using_dataloader_iter:\n            batch = trainer.precision_plugin.convert_input(batch)\n            batch = trainer.lightning_module._on_before_batch_transfer(batch, dataloader_idx=0)\n            batch = call._call_strategy_hook(trainer, \"batch_to_device\", batch, dataloader_idx=0)\n\n        self.batch_progress.increment_ready()\n        trainer._logger_connector.on_batch_start(batch)\n\n        batch_output: _BATCH_OUTPUTS_TYPE = None  # for mypy\n        should_skip_rest_of_epoch = False\n\n        if batch is None and not using_dataloader_iter:\n            self._warning_cache.warn(\"train_dataloader yielded None. If this was on purpose, ignore this warning...\")\n        else:\n            # hook\n            call._call_callback_hooks(trainer, \"on_train_batch_start\", batch, batch_idx)\n            response = call._call_lightning_module_hook(trainer, \"on_train_batch_start\", batch, batch_idx)\n            call._call_strategy_hook(trainer, \"on_train_batch_start\", batch, batch_idx)\n            should_skip_rest_of_epoch = response == -1\n            # Signal this is the last batch for the current epoch\n            if should_skip_rest_of_epoch:\n                self.batch_progress.increment_by(0, is_last_batch=True)\n            else:\n                self.batch_progress.increment_started()\n\n                kwargs = (\n                    self._build_kwargs(OrderedDict(), batch, batch_idx)\n                    if not using_dataloader_iter\n                    else OrderedDict(any=dataloader_iter)\n                )\n                with trainer.profiler.profile(\"run_training_batch\"):","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/Lightning-AI/pytorch-lightning/blob/9fed5c27d2a62ff0efd6c3573599921d6ff67c14/src/lightning/pytorch/loops/training_epoch_loop.py#L313-L349","documentation":"Training epoch loop warns when the train dataloader yields None for a batch (and dataloader_iter isn't being used). The batch is treated as absent — hooks and optimization are skipped for it.","triggerScenarios":"A train_dataloader/dataset whose __getitem__ returns None (e.g. collate producing None, or a filter that returns None instead of skipping), or a custom iterator yielding None.","commonSituations":"Data cleaning code returning None for bad samples; IterableDataset with continue-style logic that still yields None.","solutions":["Filter out invalid samples in the Dataset instead of returning None","Use a collate_fn that skips or replaces None items","If intentional (sparse batches), ignore the warning"],"exampleFix":"# before\nclass DS(Dataset):\n    def __getitem__(self, i):\n        if bad(i):\n            return None\n        return x[i]\n# after\nclass DS(Dataset):\n    def __getitem__(self, i):\n        if bad(i):\n            return self.__getitem__(i + 1)  # or prefilter indices\n        return x[i]","handlingStrategy":"validation","validationCode":"batch = next(iter(train_dl))\nassert batch is not None, 'dataloader yields None; fix dataset/collate'","typeGuard":"def dataset_yields_valid(ds) -> bool:\n    return all(ds[i] is not None for i in range(min(5, len(ds))))","tryCatchPattern":null,"preventionTips":["Never return None from __getitem__; filter indices instead","Test one batch from each dataloader in CI"],"tags":["training","dataloader","none-batch","lightning"],"backgroundTag":"dataloader-yielded-none","analyzedSha":"9fed5c27d2a62ff0efd6c3573599921d6ff67c14","analyzedAt":"2026-08-28T11:52:41.083Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}