{"record":{"id":"e07ec025927dd73e","repo":"Lightning-AI/pytorch-lightning","slug":"you-provided-only-a-single-stage-dataloader-pref","errorCode":null,"errorMessage":"You provided only a single `{stage.dataloader_prefix}_dataloader`, but have included `dataloader_idx` in `{type(pl_module).__name__}.{hook}()`. Either remove the argument or give it a default value i.e. `dataloader_idx=0`.","messagePattern":"You provided only a single `(.+?)_dataloader`, but have included `dataloader_idx` in `(.+?)\\.(.+?)\\(\\)`\\. Either remove the argument or give it a default value i\\.e\\. `dataloader_idx=0`\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/lightning/pytorch/loops/utilities.py","lineNumber":195,"sourceCode":"            context_manager = torch.no_grad\n        with context_manager():\n            return loop_run(self, *args, **kwargs)\n\n    return _decorator\n\n\ndef _verify_dataloader_idx_requirement(\n    hooks: tuple[str, ...], is_expected: bool, stage: RunningStage, pl_module: \"pl.LightningModule\"\n) -> None:\n    for hook in hooks:\n        fx = getattr(pl_module, hook)\n        # this validation only works if \"dataloader_idx\" is used, no other names such as \"dl_idx\"\n        param_present = is_param_in_hook_signature(fx, \"dataloader_idx\")\n        if not is_expected:\n            if param_present:\n                params = inspect.signature(fx).parameters\n                if \"dataloader_idx\" in params and params[\"dataloader_idx\"].default is inspect.Parameter.empty:\n                    raise RuntimeError(\n                        f\"You provided only a single `{stage.dataloader_prefix}_dataloader`, but have included \"\n                        f\"`dataloader_idx` in `{type(pl_module).__name__}.{hook}()`. Either remove the\"\n                        \" argument or give it a default value i.e. `dataloader_idx=0`.\"\n                    )\n        elif not param_present:\n            raise RuntimeError(\n                f\"You provided multiple `{stage.dataloader_prefix}_dataloader`, but no `dataloader_idx`\"\n                f\" argument in `{type(pl_module).__name__}.{hook}()`. Try adding `dataloader_idx=0` to its\"\n                \" signature.\"\n            )\n","sourceCodeStart":177,"sourceCodeEnd":206,"githubUrl":"https://github.com/Lightning-AI/pytorch-lightning/blob/9fed5c27d2a62ff0efd6c3573599921d6ff67c14/src/lightning/pytorch/loops/utilities.py#L177-L206","documentation":"Raised by _verify_dataloader_idx_requirement when a single {train/val/test/predict}_dataloader was provided but the corresponding step hook (e.g. training_step) declares a required `dataloader_idx` parameter with no default. Lightning would have to pass an index that does not exist for a single loader, so the signature is rejected.","triggerScenarios":"`def training_step(self, batch, batch_idx, dataloader_idx):` while passing one dataloader (not a list) to fit; removing a second dataloader from a datamodule without simplifying the step signature.","commonSituations":"Downsizing an experiment from multi-dataloader to single dataloader; sharing a LightningModule between single- and multi-loader experiments.","solutions":["Give the parameter a default: `def training_step(self, batch, batch_idx, dataloader_idx=0)`","Or remove `dataloader_idx` from the signature entirely for single-loader setups","Or pass a list of dataloaders so the index is meaningful"],"exampleFix":"# before\ndef training_step(self, batch, batch_idx, dataloader_idx):\n    ...\ntrainer.fit(model, single_loader)\n\n# after\ndef training_step(self, batch, batch_idx, dataloader_idx=0):\n    ...\ntrainer.fit(model, single_loader)","handlingStrategy":"validation","validationCode":"import inspect\n\nparams = inspect.signature(model.training_step).parameters\nn_loaders = 1 if not isinstance(train_dataloader, (list, tuple)) else len(train_dataloader)\nif n_loaders == 1 and 'dataloader_idx' in params:\n    assert params['dataloader_idx'].default is not inspect.Parameter.empty, 'give dataloader_idx a default'","typeGuard":"def signature_ok_single_loader(fn) -> bool:\n    p = inspect.signature(fn).parameters.get('dataloader_idx')\n    return p is None or p.default is not inspect.Parameter.empty","tryCatchPattern":null,"preventionTips":["Always declare `dataloader_idx=0` with a default so hooks work for both single and multiple loaders","Re-run fast_dev_run after changing dataloader counts"],"tags":["pytorch-lightning","dataloader-idx","hook-signature","single-dataloader"],"backgroundTag":"hook-signature-mismatch","analyzedSha":"9fed5c27d2a62ff0efd6c3573599921d6ff67c14","analyzedAt":"2026-08-28T11:52:41.083Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}