{"record":{"id":"1ebe823b5389192b","repo":"Lightning-AI/pytorch-lightning","slug":"with-def-training-step-self-dataloader-iter","errorCode":null,"errorMessage":"With `def training_step(self, dataloader_iter)`, `self.log(..., batch_size=...)` should be provided.","messagePattern":"With `def training_step\\(self, dataloader_iter\\)`, `self\\.log\\(\\.\\.\\., batch_size=\\.\\.\\.\\)` should be provided\\.","errorType":"exception","errorClass":"MisconfigurationException","httpStatus":null,"severity":"error","filePath":"src/lightning/pytorch/core/module.py","lineNumber":518,"sourceCode":"                    raise MisconfigurationException(\n                        \"Could not find the `LightningModule` attribute for the `torchmetrics.Metric` logged.\"\n                        \" You can fix this by setting an attribute for the metric in your `LightningModule`.\"\n                    )\n            # try to find the passed metric in the LightningModule\n            metric_attribute = self._metric_attributes.get(id(value), None)\n            if metric_attribute is None:\n                raise MisconfigurationException(\n                    \"Could not find the `LightningModule` attribute for the `torchmetrics.Metric` logged.\"\n                    f\" You can fix this by calling `self.log({name}, ..., metric_attribute=name)` where `name` is one\"\n                    f\" of {list(self._metric_attributes.values())}\"\n                )\n\n        if (\n            trainer.training\n            and is_param_in_hook_signature(self.training_step, \"dataloader_iter\", explicit=True)\n            and batch_size is None\n        ):\n            raise MisconfigurationException(\n                \"With `def training_step(self, dataloader_iter)`, `self.log(..., batch_size=...)` should be provided.\"\n            )\n\n        if logger and trainer.logger is None:\n            rank_zero_warn(\n                f\"You called `self.log({name!r}, ..., logger=True)` but have no logger configured. You can enable one\"\n                \" by doing `Trainer(logger=ALogger(...))`\"\n            )\n        if logger is None:\n            # we could set false here if there's no configured logger, however, we still need to compute the \"logged\"\n            # metrics anyway because that's what the evaluation loops use as return value\n            logger = True\n\n        results.log(\n            self._current_fx_name,\n            name,\n            value,\n            prog_bar=prog_bar,","sourceCodeStart":500,"sourceCodeEnd":536,"githubUrl":"https://github.com/Lightning-AI/pytorch-lightning/blob/9fed5c27d2a62ff0efd6c3573599921d6ff67c14/src/lightning/pytorch/core/module.py#L500-L536","documentation":"When training_step is declared as def training_step(self, dataloader_iter), Lightning cannot infer the batch size from a batch argument. self.log uses batch size for correct metric aggregation/logging, so you must pass it explicitly whenever logging in that mode.","triggerScenarios":"Defining training_step(self, dataloader_iter) (iterable-style dataloader) and calling self.log('loss', loss) without batch_size=... during training.","commonSituations":"User switched to dataloader_iter signature to unpack data lazily (e.g. streaming, fused dataloaders) and kept old self.log calls; tutorial code migrated from batch-style signature.","solutions":["Pass the batch size explicitly: self.log('loss', loss, batch_size=batch_size) where batch_size comes from your extracted batch","Extract batch via batch, _ = next(dataloader_iter) and compute its size, then pass it to every self.log call in training_step","Alternatively revert to def training_step(self, batch, batch_idx) so the Trainer infers batch_size"],"exampleFix":"# before\ndef training_step(self, dataloader_iter):\n    batch, _ = next(dataloader_iter)\n    loss = self.step(batch)\n    self.log('loss', loss)  # raises\n\n# after\ndef training_step(self, dataloader_iter):\n    batch, _ = next(dataloader_iter)\n    loss = self.step(batch)\n    self.log('loss', loss, batch_size=len(batch['x']))","handlingStrategy":"validation","validationCode":"if batch_size is None:\n    batch_size = infer_batch_size(batch)  # e.g. batch['x'].shape[0] or len(next(iter))[0])\nself.log('loss', loss, batch_size=batch_size)","typeGuard":"def uses_dataloader_iter(module) -> bool:\n    from lightning.pytorch.utilities.model_helpers import is_param_in_hook_signature\n    return is_param_in_hook_signature(module.training_step, 'dataloader_iter', explicit=True)","tryCatchPattern":null,"preventionTips":["Always pass batch_size to self.log when using dataloader_iter-style training_step","Write a helper that computes batch_size once per step and reuses it for all log calls"],"tags":["pytorch-lightning","self-log","dataloader-iter","batch-size","training-step"],"backgroundTag":"logging-outside-training-loop","analyzedSha":"9fed5c27d2a62ff0efd6c3573599921d6ff67c14","analyzedAt":"2026-08-28T11:52:41.083Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}