Lightning-AI/pytorch-lightning · error · MisconfigurationException

"You cannot pass `train_dataloader` or `val_dataloaders` to

Error message

"You cannot pass `train_dataloader` or `val_dataloaders` to `trainer.fit(datamodule=...)`"

What it means

trainer.fit() was called with both a datamodule and explicit train_dataloaders/val_dataloaders. Lightning cannot decide which data source to use, so it raises MisconfigurationException. Note that a LightningDataModule passed positionally is detected and reassigned, but explicit dataloaders alongside a datamodule keyword are not allowed.

Source

Thrown at src/lightning/pytorch/trainer/trainer.py:618

    def _fit_impl(
        self,
        model: "pl.LightningModule",
        train_dataloaders: Optional[Union[TRAIN_DATALOADERS, LightningDataModule]] = None,
        val_dataloaders: Optional[EVAL_DATALOADERS] = None,
        datamodule: Optional[LightningDataModule] = None,
        ckpt_path: Optional[_PATH] = None,
        weights_only: Optional[bool] = None,
    ) -> None:
        log.debug(f"{self.__class__.__name__}: trainer fit stage")

        # if a datamodule comes in as the second arg, then fix it for the user
        if isinstance(train_dataloaders, LightningDataModule):
            datamodule = train_dataloaders
            train_dataloaders = None
        # If you supply a datamodule you can't supply train_dataloader or val_dataloaders
        if (train_dataloaders is not None or val_dataloaders is not None) and datamodule is not None:
            raise MisconfigurationException(
                "You cannot pass `train_dataloader` or `val_dataloaders` to `trainer.fit(datamodule=...)`"
            )

        # links data to the trainer
        self._data_connector.attach_data(
            model, train_dataloaders=train_dataloaders, val_dataloaders=val_dataloaders, datamodule=datamodule
        )

        assert self.state.fn is not None
        if _is_registry(ckpt_path) and module_available("litmodels"):
            download_model_from_registry(ckpt_path, self)
        ckpt_path = self._checkpoint_connector._select_ckpt_path(
            self.state.fn,
            ckpt_path,
            model_provided=True,
            model_connected=self.lightning_module is not None,
        )
        self._run(model, ckpt_path=ckpt_path, weights_only=weights_only)

View on GitHub (pinned to 9fed5c27d2)

Solutions

  1. Remove the dataloader arguments and let the datamodule provide train_dataloaders()/val_dataloaders()
  2. Or remove datamodule= and pass dataloaders directly

Example fix

# before
trainer.fit(model, train_dataloaders=train_loader, datamodule=dm)
# after
trainer.fit(model, datamodule=dm)
Defensive patterns

Strategy: validation

Validate before calling

if datamodule is not None:
    assert train_dataloaders is None and val_dataloaders is None, "pass either datamodule or dataloaders, not both"
trainer.fit(model, datamodule=datamodule)

Prevention

When it happens

Trigger: trainer.fit(model, train_dataloaders=train_loader, datamodule=dm) or trainer.fit(model, val_dataloaders=..., datamodule=dm); also trainer.fit(model, dm, train_dataloaders=...).

Common situations: Gradually migrating from dataloaders to a LightningDataModule and leaving old dataloader arguments in the fit call, or template code combining both.

Related errors


AI-assisted analysis of Lightning-AI/pytorch-lightning@9fed5c27d2 (2026-08-28). Data as JSON: /api/errors/e0c90ab0966d9814. Report an issue: GitHub.