#3707·peft

Failed adapter injection leaves orphaned adapter layers behind

Author: eSVeeFCreated Sep 9, 2026Updated Sep 17, 2026

System Info

  • Python: 3.12.3
  • PEFT: main 279fccce200686af324611d7c49e3adab60485e1
  • Accelerate: 1.13.0
  • Transformers: 5.3.0

While adding adapters to a small Mamba-like model, I ran into a case where an invalid target caused add_adapter() to fail, but the model was still partially modified.

python
import torch
from torch import nn
from peft import LoraConfig, get_peft_model


class TinyMambaLike(nn.Module):
    def __init__(self):
        super().__init__()
        self.safe = nn.Linear(4, 4, bias=False)
        self.out_proj = nn.Linear(4, 4, bias=False)
        self.config = type("Config", (), {"model_type": "mamba"})()

    def forward(self, x):
        return self.out_proj(self.safe(x))


model = get_peft_model(
    TinyMambaLike(),
    LoraConfig(target_modules=["safe"], r=2),
    adapter_name="default",
)

try:
    model.add_adapter(
        "other",
        LoraConfig(target_modules=["safe", "out_proj"], r=2),
    )
except ValueError as error:
    print(error)

print(model.peft_config.keys())
print([name for name in model.state_dict() if ".other." in name])

The second configuration is rejected because out_proj is not supported for Mamba-based models. However, safe has already been updated before the error is raised.

Observed result:

dict_keys(["default"])
[
    "base_model.model.safe.lora_A.other.weight",
    "base_model.model.safe.lora_B.other.weight",
]

The configuration is rolled back, but the partially injected "other" adapter remains in the model. The same general behavior also occurs during initial injection: an error on a later target can leave earlier targets replaced.

It looks like BaseTuner.inject_adapter() performs module replacement while traversing targets, with compatibility checks occurring as each target is processed. PeftModel.add_adapter() removes the new configuration when injection fails, but does not restore the module structure or tuner state.

I would expect a failed injection to leave the model unchanged, or at least to leave no adapter parameters that are no longer represented in peft_config.

I’d be happy to open a PR with regression coverage and a fix. But I'm not sure right now if we should validate all targets before mutating the model, or implemente a rollback mechanism that restores the module and tuner state if any injection step raises.