unslothai/unsloth · error · ValueError
duplicate LoRA id '{spec.id}'; list each adapter at most onc
Error message
duplicate LoRA id '{spec.id}'; list each adapter at most once What it means
Raised by the loras field_validator on the quantize/build request when the same LoRA id appears more than once. _resolve_lora_set suffixes colliding adapter names, so a repeated id resolves the SAME adapter twice and set_adapters stacks both copies past the per-adapter weight bound. On this path the mistake is baked into the quantized build before compilation, so it rides every generated image until a reload.
Source
Thrown at studio/backend/models/inference.py:2862
@field_validator("attention_backend", mode = "before")
@classmethod
def _normalize_attention_backend(cls, value):
# The dispatcher accepts case/whitespace variants, but the Literal above is validated before any normaliser runs, so fold it here.
return value.strip().lower() if isinstance(value, str) else value
@field_validator("loras")
@classmethod
def _unique_lora_ids(cls, value: Optional[list["LoraSpec"]]) -> Optional[list["LoraSpec"]]:
# Same guard DiffusionGenerateRequest carries, and it matters more here: _resolve_lora_set
# suffixes colliding adapter names, so a repeated id resolves the SAME adapter twice and
# set_adapters stacks both copies past the per-adapter weight bound. On the generation path
# that is one bad image; on this path the adapters are baked into the quantized build
# before compilation, so the unintended combination rides every image until a reload.
if value:
seen: set[str] = set()
for spec in value:
if spec.id in seen:
raise ValueError(
f"duplicate LoRA id '{spec.id}'; list each adapter at most once"
)
seen.add(spec.id)
return value
class LoraSpec(BaseModel):
"""One LoRA adapter to apply for a generation, referenced by its discovery id.
The id is resolved against the backend's own LoRA catalog + local scan (see
core/inference/diffusion_lora.py); the client never supplies a raw filesystem
path, so an arbitrary file can't be loaded. Weight 0 disables the adapter.
"""
id: str = Field(
..., min_length = 1, max_length = 512, description = "LoRA discovery id (repo id or local stem)"
)
weight: float = Field(View on GitHub (pinned to 203007d190)
Solutions
- Deduplicate by id client-side before submitting (keep the intended weight for each).
- To strengthen an adapter, raise its weight (0 disables; per-adapter bound applies) instead of listing it twice.
- If merging preset + user LoRA lists, make the merge key the adapter id.
Example fix
# before
loras = user_loras + preset_loras # may contain 'sketch' twice
# after
by_id = {s['id']: s for s in user_loras + preset_loras}
loras = list(by_id.values()) Defensive patterns
Strategy: validation
Validate before calling
def dedupe_loras(loras: list[dict] | None) -> list[dict] | None:
if not loras:
return loras
return list({spec['id']: spec for spec in loras}.values()) Prevention
- Key adapter selections by id in UI state so re-add replaces
- Deduplicate merged preset+user lists before submitting
- Strengthen an effect by raising weight, never by repeating the adapter
When it happens
Trigger: POSTing a quantize request with loras: [{"id": "sketch", "weight": 0.5}, {"id": "sketch", "weight": 0.3}] — an attempt to double-apply or layer the same adapter.
Common situations: Prompt-driven pipelines that merge multiple LoRA lists (user + preset) without deduping; UI state where re-adding an adapter appends instead of replaces; users trying to strengthen an effect by repeating the adapter rather than raising weight.
Related errors
- The requested LoRA adapters could not be applied: baking ada
- GGUF LoRA adapters are not supported on the diffusers engine
- LoRA is not supported for this model/quantisation on the dif
- This quantized (int8/fp8) load was built without LoRA adapte
- The LoRA selection changed, but a quantized (int8/fp8) trans
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/bbf3893e6ab15039.
Report an issue: GitHub.