Lightning-AI/pytorch-lightning · warning

You have overridden `{hook_name}` in `LightningModule` but h

Error message

You have overridden `{hook_name}` in `LightningModule` but have passed in a `LightningDataModule`. It will use the implementation from `LightningModule` instance.

What it means

Companion warning to the dual-override case: here only the LightningModule overrides the hook, but a LightningDataModule was also passed. The LightningModule's implementation is used and the datamodule's default is ignored.

Source

Thrown at src/lightning/pytorch/trainer/connectors/data_connector.py:378

        if hook_name not in self._valid_hooks:
            raise ValueError(
                f"`{hook_name}` is not a shared hook within `LightningModule` and `LightningDataModule`."
                f" Valid hooks are {self._valid_hooks}."
            )

        if self.datamodule is None:
            return self.model

        if is_overridden(hook_name, self.datamodule):
            if is_overridden(hook_name, self.model):
                warning_cache.warn(
                    f"You have overridden `{hook_name}` in both `LightningModule` and `LightningDataModule`."
                    " It will use the implementation from `LightningDataModule` instance."
                )
            return self.datamodule

        if is_overridden(hook_name, self.model):
            warning_cache.warn(
                f"You have overridden `{hook_name}` in `LightningModule` but have passed in a"
                " `LightningDataModule`. It will use the implementation from `LightningModule` instance."
            )
        return self.model


def _check_dataloader_iterable(
    dataloader: object,
    source: _DataLoaderSource,
    trainer_fn: TrainerFn,
) -> None:
    if isinstance(dataloader, DataLoader):
        # Fast path: `torch.utils.data.DataLoader` is always iterable, calling iter() would be expensive
        return

    try:
        iter(dataloader)  # type: ignore[call-overload]
    except TypeError:

View on GitHub (pinned to 9fed5c27d2)

Solutions

  1. Move the dataloader method into the DataModule for consistency
  2. Or remove the datamodule argument if the model self-provides data
  3. Accept the warning if the intent is model-supplied data

Example fix

# before
class M(LightningModule):
    def train_dataloader(self): return make_loader()
trainer.fit(M(), datamodule=dm)
# after
class DM(LightningDataModule):
    def train_dataloader(self): return make_loader()
trainer.fit(M(), datamodule=DM())
Defensive patterns

Strategy: validation

Validate before calling

from lightning.pytorch.utilities.model_helpers import is_overridden
if is_overridden('train_dataloader', model) and dm is not None:
    print('model hook will be used; datamodule ignored for this hook')

Prevention

When it happens

Trigger: Trainer(...).fit(model, datamodule=dm) where model defines train_dataloader but dm does not.

Common situations: Adding a datamodule for orchestration/defaults while keeping legacy dataloader methods in the model.

Related errors


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