{"record":{"id":"d8c1e3c0b5a633a2","repo":"Lightning-AI/pytorch-lightning","slug":"no-step-name-method-defined-to-run-trainer","errorCode":null,"errorMessage":"No `{step_name}()` method defined to run `Trainer.{trainer_method}`.","messagePattern":"No `(.+?)\\(\\)` method defined to run `Trainer\\.(.+?)`\\.","errorType":"validation","errorClass":"MisconfigurationException","httpStatus":null,"severity":"error","filePath":"src/lightning/pytorch/trainer/configuration_validator.py","lineNumber":106,"sourceCode":"            \" You can find migration examples in https://github.com/Lightning-AI/pytorch-lightning/pull/16520.\"\n        )\n\n\ndef __verify_eval_loop_configuration(model: \"pl.LightningModule\", stage: str) -> None:\n    step_name = \"validation_step\" if stage == \"val\" else f\"{stage}_step\"\n    has_step = is_overridden(step_name, model)\n\n    # predict_step is not required to be overridden\n    if stage == \"predict\":\n        if model.predict_step is None:\n            raise MisconfigurationException(\"`predict_step` cannot be None to run `Trainer.predict`\")\n        if not has_step and not is_overridden(\"forward\", model):\n            raise MisconfigurationException(\"`Trainer.predict` requires `forward` method to run.\")\n    else:\n        # verify minimum evaluation requirements\n        if not has_step:\n            trainer_method = \"validate\" if stage == \"val\" else stage\n            raise MisconfigurationException(f\"No `{step_name}()` method defined to run `Trainer.{trainer_method}`.\")\n\n        # check legacy hooks are not present\n        epoch_end_name = \"validation_epoch_end\" if stage == \"val\" else \"test_epoch_end\"\n        if callable(getattr(model, epoch_end_name, None)):\n            raise NotImplementedError(\n                f\"Support for `{epoch_end_name}` has been removed in v2.0.0. `{type(model).__name__}` implements this\"\n                f\" method. You can use the `on_{epoch_end_name}` hook instead. To access outputs, save them in-memory\"\n                \" as instance attributes.\"\n                \" You can find migration examples in https://github.com/Lightning-AI/pytorch-lightning/pull/16520.\"\n            )\n\n\ndef __verify_manual_optimization_support(trainer: \"pl.Trainer\", model: \"pl.LightningModule\") -> None:\n    if model.automatic_optimization:\n        return\n    if trainer.gradient_clip_val is not None and trainer.gradient_clip_val > 0:\n        raise MisconfigurationException(\n            \"Automatic gradient clipping is not supported for manual optimization.\"","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/Lightning-AI/pytorch-lightning/blob/9fed5c27d2a62ff0efd6c3573599921d6ff67c14/src/lightning/pytorch/trainer/configuration_validator.py#L88-L124","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"# before\nclass Model(L.LightningModule):\n    def training_step(self, batch, batch_idx): ...\ntrainer.validate(model)\n# after\nclass Model(L.LightningModule):\n    def training_step(self, batch, batch_idx): ...\n    def validation_step(self, batch, batch_idx):\n        x, y = batch\n        return self.loss(self(x), y)\ntrainer.validate(model)","handlingStrategy":"validation","validationCode":"from lightning.pytorch.core.mixins import HyperparametersMixin  # noqa\nimport inspect\n\ndef has_eval_step(model, stage):\n    # stage: 'val' | 'test' | 'predict'\n    required = {'val': 'validation_step', 'test': 'test_step'}.get(stage)\n    if required:\n        return callable(getattr(model, required, None)) and \\\n            type(model).__name__ != 'LightningModule'\n    return callable(getattr(model, 'predict_step', None)) or \\\n        ('forward' in type(model).__dict__ or any('forward' in k.__dict__ for k in type(model).__mro__[1:-1]))","typeGuard":"def supports_stage(model: \"pl.LightningModule\", stage: str) -> bool:\n    if stage in ('val', 'test'):\n        return is_overridden(f'{stage}_step', model)\n    return is_overridden('predict_step', model) or is_overridden('forward', model)","tryCatchPattern":"try:\n    trainer.validate(model)\nexcept MisconfigurationException as e:\n    if 'method defined to run' in str(e):\n        raise NotImplementedError(f'Model missing eval hook: {e}') from e\n    raise","preventionTips":["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."],"tags":["pytorch-lightning","trainer","validation","missing-hook","configuration"],"backgroundTag":"missing-required-callback","analyzedSha":"9fed5c27d2a62ff0efd6c3573599921d6ff67c14","analyzedAt":"2026-08-28T11:52:41.083Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}