{"record":{"id":"f5c00278ff68a070","repo":"Lightning-AI/pytorch-lightning","slug":"an-optimizer-should-be-passed-only-once-to-the-se-f5c002","errorCode":null,"errorMessage":"An optimizer should be passed only once to the `setup_optimizers` method.","messagePattern":"An optimizer should be passed only once to the `setup_optimizers` method\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/lightning/fabric/fabric.py","lineNumber":1235,"sourceCode":"\n    def _validate_setup_module(self, module: nn.Module) -> None:\n        self._validate_launched()\n        if isinstance(module, _FabricModule):\n            raise ValueError(\"A model should be passed only once to the `setup_module` method.\")\n\n    def _validate_setup_optimizers(self, optimizers: Sequence[Optimizer]) -> None:\n        self._validate_launched()\n        if isinstance(self._strategy, (DeepSpeedStrategy, XLAStrategy)):\n            raise RuntimeError(\n                f\"The `{type(self._strategy).__name__}` requires the model and optimizer(s) to be set up jointly\"\n                \" through `.setup(model, optimizer, ...)`.\"\n            )\n\n        if not optimizers:\n            raise ValueError(\"`setup_optimizers` requires at least one optimizer as input.\")\n\n        if any(isinstance(opt, _FabricOptimizer) for opt in optimizers):\n            raise ValueError(\"An optimizer should be passed only once to the `setup_optimizers` method.\")\n\n        if any(_has_meta_device_parameters_or_buffers(optimizer) for optimizer in optimizers):\n            raise RuntimeError(\n                \"The optimizer has references to the model's meta-device parameters. Materializing them is\"\n                \" is currently not supported. Create the optimizer after setting up the model, then call\"\n                \" `fabric.setup_optimizers(optimizer)`.\"\n            )\n\n    def _validate_setup_dataloaders(self, dataloaders: Sequence[DataLoader]) -> None:\n        self._validate_launched()\n        if not dataloaders:\n            raise ValueError(\"`setup_dataloaders` requires at least one dataloader as input.\")\n\n        if any(isinstance(dl, _FabricDataLoader) for dl in dataloaders):\n            raise ValueError(\"A dataloader should be passed only once to the `setup_dataloaders` method.\")\n\n        if any(not isinstance(dl, DataLoader) for dl in dataloaders):\n            raise TypeError(\"Only PyTorch DataLoader are currently supported in `setup_dataloaders`.\")","sourceCodeStart":1217,"sourceCodeEnd":1253,"githubUrl":"https://github.com/Lightning-AI/pytorch-lightning/blob/9fed5c27d2a62ff0efd6c3573599921d6ff67c14/src/lightning/fabric/fabric.py#L1217-L1253","documentation":"Raised when any optimizer passed to `fabric.setup_optimizers()` is already a `_FabricOptimizer`, i.e. it was already wrapped by a previous `setup`/`setup_optimizers` call. Fabric guards against double-wrapping because wrapping twice would break state loading, stepping, and strategy hooks.","triggerScenarios":"Calling `fabric.setup(model, optimizer)` and then `fabric.setup_optimizers(optimizer)` on the returned (already wrapped) optimizer; calling `setup_optimizers` twice with the same optimizer; mixing `fabric.setup(...)` and `setup_optimizers` in a migration.","commonSituations":"Migrating a script from `fabric.setup(model, optimizer)` to separate `setup(model)` + `setup_optimizers(optimizer)` and forgetting that setup already wraps optimizers; copy-pasting setup calls; loops that set up the same optimizer twice.","solutions":["Keep the unwrapped `torch.optim.Optimizer` around and pass that to setup_optimizers, discarding the wrapped return value references","If using `fabric.setup(model, optimizer)`, do not also call `setup_optimizers`","Audit the call order: setup the model first, create the optimizer from the setup model's parameters, then call setup_optimizers once"],"exampleFix":"# before\nmodel, optimizer = fabric.setup(model, optimizer)\nfabric.setup_optimizers(optimizer)  # ValueError\n\n# after\nmodel, optimizer = fabric.setup(model, optimizer)\n# do not call setup_optimizers again","handlingStrategy":"validation","validationCode":"from lightning.fabric.optimizers import _FabricOptimizer\nraw = [o for o in optimizers if not isinstance(o, _FabricOptimizer)]\nassert raw, 'no optimizer to set up'","typeGuard":"from lightning.fabric.optimizers import _FabricOptimizer\nfrom torch.optim import Optimizer\ndef is_raw_optimizer(o) -> bool:\n    return isinstance(o, Optimizer) and not isinstance(o, _FabricOptimizer)","tryCatchPattern":null,"preventionTips":["Keep original (unwrapped) references to optimizers","Adopt one setup path: either fabric.setup(model, optimizer) or split setup, never both"],"tags":["pytorch-lightning","fabric","optimizer","double-setup"],"backgroundTag":"double-initialization","analyzedSha":"9fed5c27d2a62ff0efd6c3573599921d6ff67c14","analyzedAt":"2026-08-28T11:52:41.083Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}