Lightning-AI/pytorch-lightning · error · ValueError
A dataloader should be passed only once to the `setup_datalo
Error message
A dataloader should be passed only once to the `setup_dataloaders` method.
What it means
Raised when a dataloader passed to `fabric.setup_dataloaders()` is already a `_FabricDataLoader`, i.e. it was already wrapped by a previous setup call. Double-wrapping would break iteration and distributed sharding, so Fabric rejects it.
Source
Thrown at src/lightning/fabric/fabric.py:1250
raise ValueError("`setup_optimizers` requires at least one optimizer as input.")
if any(isinstance(opt, _FabricOptimizer) for opt in optimizers):
raise ValueError("An optimizer should be passed only once to the `setup_optimizers` method.")
if any(_has_meta_device_parameters_or_buffers(optimizer) for optimizer in optimizers):
raise RuntimeError(
"The optimizer has references to the model's meta-device parameters. Materializing them is"
" is currently not supported. Create the optimizer after setting up the model, then call"
" `fabric.setup_optimizers(optimizer)`."
)
def _validate_setup_dataloaders(self, dataloaders: Sequence[DataLoader]) -> None:
self._validate_launched()
if not dataloaders:
raise ValueError("`setup_dataloaders` requires at least one dataloader as input.")
if any(isinstance(dl, _FabricDataLoader) for dl in dataloaders):
raise ValueError("A dataloader should be passed only once to the `setup_dataloaders` method.")
if any(not isinstance(dl, DataLoader) for dl in dataloaders):
raise TypeError("Only PyTorch DataLoader are currently supported in `setup_dataloaders`.")
@staticmethod
def _configure_callbacks(callbacks: Optional[Union[list[Any], Any]]) -> list[Any]:
callbacks = callbacks if callbacks is not None else []
callbacks = callbacks if isinstance(callbacks, list) else [callbacks]
callbacks.extend(_load_external_callbacks("lightning.fabric.callbacks_factory"))
return callbacks
View on GitHub (pinned to 9fed5c27d2)
Solutions
- Keep the raw `DataLoader` objects and pass each only once to setup_dataloaders; use the wrapped return value for training/evaluation only
- Consolidate into a single call: `train_dl, val_dl = fabric.setup_dataloaders(train_dl, val_dl)`
- Check helper utilities for hidden setup calls
Example fix
# before train_dl = fabric.setup_dataloaders(train_dl) train_dl, val_dl = fabric.setup_dataloaders(train_dl, val_dl) # ValueError # after train_dl, val_dl = fabric.setup_dataloaders(train_dl, val_dl)
Defensive patterns
Strategy: validation
Validate before calling
from lightning.fabric.utilities.data import _FabricDataLoader assert all(not isinstance(dl, _FabricDataLoader) for dl in dls), 'already wrapped'
Type guard
from torch.utils.data import DataLoader
from lightning.fabric.utilities.data import _FabricDataLoader
def is_raw_dataloader(dl) -> bool:
return isinstance(dl, DataLoader) and not isinstance(dl, _FabricDataLoader) Prevention
- Set up each dataloader exactly once; use wrapped results only for iteration
- Prefer one combined setup_dataloaders call per script
When it happens
Trigger: Calling `fabric.setup_dataloaders(dl)` twice with the same dataloader; keeping a reference to the wrapped return value and passing it to a second setup call (e.g. setting up train and val loaders that share one already-wrapped loader).
Common situations: Setting up multiple phases (train/val/test) in separate calls and accidentally reusing an already-wrapped loader; helper functions that call setup_dataloaders internally being called on already-prepared inputs.
Related errors
- An optimizer should be passed only once to the `setup_optimi
- `setup_dataloaders` requires at least one dataloader as inpu
- Only PyTorch DataLoader are currently supported in `setup_da
- A model should be passed only once to the `setup` method.
- An optimizer should be passed only once to the `setup` metho
AI-assisted analysis of Lightning-AI/pytorch-lightning@9fed5c27d2 (2026-08-28).
Data as JSON: /api/errors/f660bdab0014b6d9.
Report an issue: GitHub.