Lightning-AI/pytorch-lightning · error · MisconfigurationException
No `{step_name}()` method defined to run `Trainer.{trainer_m
Error message
No `{step_name}()` method defined to run `Trainer.{trainer_method}`. What it means
Raised by Lightning's configuration validator before starting validation or prediction: the LightningModule does not implement the required step method for the requested stage. `Trainer.validate()` needs `validation_step`, `Trainer.test()` needs `test_step`, and evaluation during `predict` requires `forward` or a step. The check runs when `trainer.fit`/`validate`/`test`/`predict` is called.
Source
Thrown at src/lightning/pytorch/trainer/configuration_validator.py:106
" You can find migration examples in https://github.com/Lightning-AI/pytorch-lightning/pull/16520."
)
def __verify_eval_loop_configuration(model: "pl.LightningModule", stage: str) -> None:
step_name = "validation_step" if stage == "val" else f"{stage}_step"
has_step = is_overridden(step_name, model)
# predict_step is not required to be overridden
if stage == "predict":
if model.predict_step is None:
raise MisconfigurationException("`predict_step` cannot be None to run `Trainer.predict`")
if not has_step and not is_overridden("forward", model):
raise MisconfigurationException("`Trainer.predict` requires `forward` method to run.")
else:
# verify minimum evaluation requirements
if not has_step:
trainer_method = "validate" if stage == "val" else stage
raise MisconfigurationException(f"No `{step_name}()` method defined to run `Trainer.{trainer_method}`.")
# check legacy hooks are not present
epoch_end_name = "validation_epoch_end" if stage == "val" else "test_epoch_end"
if callable(getattr(model, epoch_end_name, None)):
raise NotImplementedError(
f"Support for `{epoch_end_name}` has been removed in v2.0.0. `{type(model).__name__}` implements this"
f" method. You can use the `on_{epoch_end_name}` hook instead. To access outputs, save them in-memory"
" as instance attributes."
" You can find migration examples in https://github.com/Lightning-AI/pytorch-lightning/pull/16520."
)
def __verify_manual_optimization_support(trainer: "pl.Trainer", model: "pl.LightningModule") -> None:
if model.automatic_optimization:
return
if trainer.gradient_clip_val is not None and trainer.gradient_clip_val > 0:
raise MisconfigurationException(
"Automatic gradient clipping is not supported for manual optimization."View on GitHub (pinned to 9fed5c27d2)
Solutions
- Implement the missing hook on your LightningModule: `validation_step` for `Trainer.validate`, `test_step` for `Trainer.test`, `predict_step` (or `forward`) for `Trainer.predict`.
- If you only meant to run inference, use `trainer.predict` with `forward` defined instead of `validate`.
- Verify the model instance you passed is the one with the hooks defined (not the base class or a fresh skeleton).
Example fix
# before
class Model(L.LightningModule):
def training_step(self, batch, batch_idx): ...
trainer.validate(model)
# after
class Model(L.LightningModule):
def training_step(self, batch, batch_idx): ...
def validation_step(self, batch, batch_idx):
x, y = batch
return self.loss(self(x), y)
trainer.validate(model) Defensive patterns
Strategy: validation
Validate before calling
from lightning.pytorch.core.mixins import HyperparametersMixin # noqa
import inspect
def has_eval_step(model, stage):
# stage: 'val' | 'test' | 'predict'
required = {'val': 'validation_step', 'test': 'test_step'}.get(stage)
if required:
return callable(getattr(model, required, None)) and \
type(model).__name__ != 'LightningModule'
return callable(getattr(model, 'predict_step', None)) or \
('forward' in type(model).__dict__ or any('forward' in k.__dict__ for k in type(model).__mro__[1:-1])) Type guard
def supports_stage(model: "pl.LightningModule", stage: str) -> bool:
if stage in ('val', 'test'):
return is_overridden(f'{stage}_step', model)
return is_overridden('predict_step', model) or is_overridden('forward', model) Try / catch
try:
trainer.validate(model)
except MisconfigurationException as e:
if 'method defined to run' in str(e):
raise NotImplementedError(f'Model missing eval hook: {e}') from e
raise Prevention
- Define validation_step/test_step in base model classes used for evaluation.
- Assert required hooks exist before launching training in CI smoke tests.
- When refactoring, grep for trainer.validate/test calls and check the model implements the matching step.
When it happens
Trigger: Calling `trainer.validate(model)` without `def validation_step` overridden, `trainer.test(model)` without `test_step`, or `trainer.predict()` with neither a stage step nor `forward` overridden on the LightningModule.
Common situations: Copy-pasting a training-only model and calling validate/test; renaming hooks after migrating to Lightning 2.0; subclassing a base module that doesn't define the eval step; calling predict on a model whose forward is consumed by a decorator or renamed.
Related errors
- `max_epochs` must be a non-negative integer or -1. You passe
- Device should be CUDA, got {device} instead.
- You requested to find {num_devices} devices but there are no
- `max_steps` must be a non-negative integer or -1 (infinite s
- You requested to find {num_devices} devices but this machine
AI-assisted analysis of Lightning-AI/pytorch-lightning@9fed5c27d2 (2026-08-28).
Data as JSON: /api/errors/d8c1e3c0b5a633a2.
Report an issue: GitHub.