{"record":{"id":"390959db51aca3d9","repo":"Lightning-AI/pytorch-lightning","slug":"self-class-qualname-is-not-attached-to-a","errorCode":null,"errorMessage":"{self.__class__.__qualname__} is not attached to a `Trainer`.","messagePattern":"(.+?) is not attached to a `Trainer`\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/lightning/pytorch/core/module.py","lineNumber":218,"sourceCode":"        if not self.trainer.lr_scheduler_configs:\n            return None\n\n        # ignore other keys \"interval\", \"frequency\", etc.\n        lr_schedulers: list[LRSchedulerPLType] = [config.scheduler for config in self.trainer.lr_scheduler_configs]\n\n        # single scheduler\n        if len(lr_schedulers) == 1:\n            return lr_schedulers[0]\n\n        # multiple schedulers\n        return lr_schedulers\n\n    @property\n    def trainer(self) -> \"pl.Trainer\":\n        if self._fabric is not None:\n            return _TrainerFabricShim(fabric=self._fabric)  # type: ignore[return-value]\n        if not self._jit_is_scripting and self._trainer is None:\n            raise RuntimeError(f\"{self.__class__.__qualname__} is not attached to a `Trainer`.\")\n        return self._trainer  # type: ignore[return-value]\n\n    @trainer.setter\n    def trainer(self, trainer: Optional[\"pl.Trainer\"]) -> None:\n        for v in self.children():\n            if isinstance(v, LightningModule):\n                v.trainer = trainer\n        self._trainer = trainer\n\n    @property\n    def fabric(self) -> Optional[\"lf.Fabric\"]:\n        return self._fabric\n\n    @fabric.setter\n    def fabric(self, fabric: Optional[\"lf.Fabric\"]) -> None:\n        for v in self.children():\n            if isinstance(v, LightningModule):\n                v.fabric = fabric","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/Lightning-AI/pytorch-lightning/blob/9fed5c27d2a62ff0efd6c3573599921d6ff67c14/src/lightning/pytorch/core/module.py#L200-L236","documentation":"LightningModule.trainer raises RuntimeError when accessed before the Trainer has attached itself to the module (which happens inside trainer.fit/validate/test/predict). Any property/method that reads self.trainer outside Trainer-managed control flow will fail. A special case returns a shim when the module is attached to Fabric instead.","triggerScenarios":"Accessing self.trainer (directly or via self.log, self.device in some paths, checkpoint saving code) in __init__, in a plain script before trainer.fit, or in a datamodule hook not driven by the Trainer.","commonSituations":"Calling model.trainer in unit tests without a Trainer; using self.trainer.global_step in __init__; accessing trainer-dependent attributes when running the module standalone or with Fabric (where _fabric shim applies only if attached).","solutions":["Move trainer-dependent logic into hooks that run under Trainer control (on_train_start, training_step, etc.)","If testing, attach a Trainer first or mock the attribute","Check `model._trainer is not None` (or use getattr guard) before accessing .trainer","For Fabric workflows, attach the module via fabric.setup(model) so the shim is returned"],"exampleFix":"# before\nclass M(L.LightningModule):\n    def __init__(self):\n        super().__init__()\n        print(self.trainer.max_epochs)  # RuntimeError\n\n# after\nclass M(L.LightningModule):\n    def on_train_start(self):\n        print(self.trainer.max_epochs)  # Trainer attached here","handlingStrategy":"validation","validationCode":"if model._trainer is None and model._fabric is None:\n    raise RuntimeError('attach model to a Trainer (trainer.fit) before accessing model.trainer')","typeGuard":"def is_attached(module) -> bool:\n    return module._trainer is not None or module._fabric is not None","tryCatchPattern":"try:\n    t = model.trainer\nexcept RuntimeError as e:\n    if 'not attached' in str(e):\n        t = None  # defer trainer-dependent logic to hooks\n    else:\n        raise","preventionTips":["Never read self.trainer in __init__ or plain functions","Keep trainer-dependent logic in hooks like on_train_start/setup"],"tags":["pytorch-lightning","lightning-module","trainer","lifecycle","not-attached"],"backgroundTag":"module-not-attached-to-trainer","analyzedSha":"9fed5c27d2a62ff0efd6c3573599921d6ff67c14","analyzedAt":"2026-08-28T11:52:41.083Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}