{"record":{"id":"c68dd17bd31d3de9","repo":"Lightning-AI/pytorch-lightning","slug":"lightning-can-t-inject-a-distributed-sampler-in-c68dd1","errorCode":null,"errorMessage":" Lightning can't inject a (distributed) sampler into your batch sampler, because it doesn't subclass PyTorch's `BatchSampler`. To mitigate this, either follow the API of `BatchSampler` and instantiate your custom batch sampler inside the `*_dataloader` hook of your module, or set `Trainer(use_distributed_sampler=False)`. If you choose the latter, you will be responsible for handling the distributed sampling within your batch sampler.","messagePattern":" Lightning can't inject a \\(distributed\\) sampler into your batch sampler, because it doesn't subclass PyTorch's `BatchSampler`\\. To mitigate this, either follow the API of `BatchSampler` and instantiate your custom batch sampler inside the `\\*_dataloader` hook of your module, or set `Trainer\\(use_distributed_sampler=False\\)`\\. If you choose the latter, you will be responsible for handling the distributed sampling within your batch sampler\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/lightning/pytorch/utilities/data.py","lineNumber":299,"sourceCode":"            # This is a sampler for which we could not capture the init args, but it kinda looks like a batch sampler\n            # even if it does not inherit from PyTorch's interface.\n            try:\n                batch_sampler = batch_sampler_cls(\n                    sampler,\n                    batch_size=batch_sampler.batch_size,\n                    drop_last=(False if is_predicting else batch_sampler.drop_last),\n                )\n            except TypeError as ex:\n                import re\n\n                match = re.match(r\".*__init__\\(\\) (got multiple values)|(missing \\d required)\", str(ex))\n                if not match:\n                    # an unexpected `TypeError`, continue failure\n                    raise\n\n                # There could either be too few or too many arguments. Customizing the message based on this doesn't\n                # make much sense since our MisconfigurationException is going to be raised from the original one.\n                raise TypeError(\n                    \" Lightning can't inject a (distributed) sampler into your batch sampler, because it doesn't\"\n                    \" subclass PyTorch's `BatchSampler`. To mitigate this, either follow the API of `BatchSampler` and\"\n                    \" instantiate your custom batch sampler inside the `*_dataloader` hook of your module,\"\n                    \" or set `Trainer(use_distributed_sampler=False)`. If you choose the latter, you will be\"\n                    \" responsible for handling the distributed sampling within your batch sampler.\"\n                ) from ex\n        elif is_predicting:\n            rank_zero_warn(\n                f\"You are using a custom batch sampler `{batch_sampler_cls.__qualname__}` for prediction.\"\n                \" Lightning would normally set `drop_last=False` to ensure all samples are returned, but for\"\n                \" custom samplers it can't guarantee this. Make sure your sampler is configured correctly to return\"\n                \" all indices.\",\n                category=PossibleUserWarning,\n            )\n        else:\n            # The sampler is not a PyTorch `BatchSampler`, we don't know how to inject a custom sampler or\n            # how to adjust the `drop_last` value\n            raise TypeError(","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/Lightning-AI/pytorch-lightning/blob/9fed5c27d2a62ff0efd6c3573599921d6ff67c14/src/lightning/pytorch/utilities/data.py#L281-L317","documentation":"Raised as a TypeError (chained from an earlier TypeError) when Lightning attempts to rebuild a custom batch sampler by calling it with PyTorch BatchSampler-style arguments and the call fails in an unexpected way; because the class does not subclass torch.utils.data.sampler.BatchSampler, Lightning cannot safely inject a (distributed) sampler. The message lists two mitigations: follow the BatchSampler API inside a *_dataloader hook, or disable Lightning's sampler replacement.","triggerScenarios":"DataLoader with a non-BatchSampler batch_sampler class whose reinstantiation with standard args raises an unexpected TypeError during distributed sampler replacement in _dataloader_init_kwargs_resolve_sampler.","commonSituations":"Custom batch sampler classes that accept incompatible positional args; versions of PyTorch where BatchSampler's signature changed; distributed training with elaborate custom samplers.","solutions":["Make your batch sampler subclass torch.utils.data.sampler.BatchSampler (sampler, batch_size, drop_last attributes)","Set Trainer(use_distributed_sampler=False) and implement distributed logic yourself","Instantiate the custom batch sampler inside the *_dataloader hook so Lightning handles it"],"exampleFix":"# before\nclass MyBatchSampler:  # duck-typed, not a BatchSampler\n    ...\n\n# after\nfrom torch.utils.data import BatchSampler\nclass MyBatchSampler(BatchSampler):\n    ...","handlingStrategy":"type-guard","validationCode":"from torch.utils.data import BatchSampler\nassert isinstance(loader.batch_sampler, BatchSampler), 'batch_sampler must subclass BatchSampler for distributed runs'","typeGuard":"from torch.utils.data import BatchSampler\nfrom typing import Any\n\ndef is_batch_sampler(obj: Any) -> bool:\n    return isinstance(obj, BatchSampler)","tryCatchPattern":null,"preventionTips":["Subclass torch.utils.data.sampler.BatchSampler for anything passed as batch_sampler","Pin PyTorch/Lightning versions in CI to catch BatchSampler signature drift","Disable Lightning sampler injection when using bespoke batch samplers"],"tags":["pytorch-lightning","batch-sampler","distributed-training","typeerror"],"backgroundTag":"custom-batch-sampler-injection-failed","analyzedSha":"9fed5c27d2a62ff0efd6c3573599921d6ff67c14","analyzedAt":"2026-08-28T11:52:41.083Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}