{"record":{"id":"4861cd5dfc9597d7","repo":"Lightning-AI/pytorch-lightning","slug":"you-cannot-pass-both-trainer-test-dataloaders","errorCode":null,"errorMessage":"You cannot pass both `trainer.test(dataloaders=..., datamodule=...)`","messagePattern":"You cannot pass both `trainer\\.test\\(dataloaders=\\.\\.\\., datamodule=\\.\\.\\.\\)`","errorType":"validation","errorClass":"MisconfigurationException","httpStatus":null,"severity":"error","filePath":"src/lightning/pytorch/trainer/trainer.py","lineNumber":851,"sourceCode":"        model: Optional[\"pl.LightningModule\"] = None,\n        dataloaders: Optional[Union[EVAL_DATALOADERS, LightningDataModule]] = None,\n        ckpt_path: Optional[_PATH] = None,\n        verbose: bool = True,\n        datamodule: Optional[LightningDataModule] = None,\n        weights_only: Optional[bool] = None,\n    ) -> Optional[Union[_PREDICT_OUTPUT, _EVALUATE_OUTPUT]]:\n        # --------------------\n        # SETUP HOOK\n        # --------------------\n        log.debug(f\"{self.__class__.__name__}: trainer test stage\")\n\n        # if a datamodule comes in as the second arg, then fix it for the user\n        if isinstance(dataloaders, LightningDataModule):\n            datamodule = dataloaders\n            dataloaders = None\n        # If you supply a datamodule you can't supply test_dataloaders\n        if dataloaders is not None and datamodule:\n            raise MisconfigurationException(\"You cannot pass both `trainer.test(dataloaders=..., datamodule=...)`\")\n\n        if model is None:\n            model = self.lightning_module\n            model_provided = False\n        else:\n            model_provided = True\n\n        self.test_loop.verbose = verbose\n\n        # links data to the trainer\n        self._data_connector.attach_data(model, test_dataloaders=dataloaders, datamodule=datamodule)\n\n        assert self.state.fn is not None\n        if _is_registry(ckpt_path) and module_available(\"litmodels\"):\n            download_model_from_registry(ckpt_path, self)\n        ckpt_path = self._checkpoint_connector._select_ckpt_path(\n            self.state.fn, ckpt_path, model_provided=model_provided, model_connected=self.lightning_module is not None\n        )","sourceCodeStart":833,"sourceCodeEnd":869,"githubUrl":"https://github.com/Lightning-AI/pytorch-lightning/blob/9fed5c27d2a62ff0efd6c3573599921d6ff67c14/src/lightning/pytorch/trainer/trainer.py#L833-L869","documentation":"trainer.test() received both dataloaders and datamodule. Lightning allows exactly one data source per call and raises MisconfigurationException when both are given. A datamodule passed positionally (as the dataloaders slot) is detected and reassigned automatically.","triggerScenarios":"trainer.test(model, dataloaders=test_loader, datamodule=dm); also trainer.test(model, dm, dataloaders=test_loader).","commonSituations":"Copy-pasting evaluation boilerplate that mixes explicit test dataloaders with a shared datamodule.","solutions":["Remove dataloaders= and implement test_dataloader() in the datamodule","Or remove datamodule= and pass the dataloader only"],"exampleFix":"# before\ntrainer.test(model, dataloaders=test_loader, datamodule=dm)\n# after\ntrainer.test(model, datamodule=dm)","handlingStrategy":"validation","validationCode":"if dataloaders is not None and datamodule is not None:\n    raise ValueError(\"pass either dataloaders or datamodule to test(), not both\")\ntrainer.test(model, dataloaders=dataloaders, datamodule=datamodule)","typeGuard":"def test_args_ok(dls, dm) -> bool:\n    return not (dls is not None and dm is not None)","tryCatchPattern":null,"preventionTips":["Centralize data-source selection in one place so all entrypoints stay consistent"],"tags":["trainer","test","datamodule","dataloader","misconfiguration","pytorch-lightning"],"backgroundTag":"conflicting-data-source-arguments","analyzedSha":"9fed5c27d2a62ff0efd6c3573599921d6ff67c14","analyzedAt":"2026-08-28T11:52:41.083Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}