invoke-ai/InvokeAI · error · ValueError
LLLite module '{name}' targets block {block_idx}, but the tr
Error message
LLLite module '{name}' targets block {block_idx}, but the transformer has only {len(blocks)} blocks What it means
After the module name parses, _resolve_target checks the block index against the transformer's actual depth. If the name targets block N but transformer.blocks has fewer than N+1 blocks, the layer does not exist and the library raises ValueError rather than indexing out of range.
Source
Thrown at invokeai/backend/anima/control_net_lllite.py:547
LIFO contract: each bind saves the forward that was CURRENT at bind
time, so when multiple adapters are stacked on one transformer they
must be restored in reverse apply order. Restoring an earlier adapter
first would delete a later adapter's wrapper and re-pin the earlier
one's saved forward.
"""
for m in self.lllite_modules:
m.unbind()
@staticmethod
def _resolve_target(transformer: nn.Module, name: str) -> nn.Module:
match = MODULE_NAME_PATTERN.match(name)
if match is None:
raise ValueError(f"Unrecognized LLLite module name: '{name}'")
block_idx = int(match.group(1))
blocks = transformer.blocks
if block_idx >= len(blocks):
raise ValueError(
f"LLLite module '{name}' targets block {block_idx}, but the transformer has only {len(blocks)} blocks"
)
target: nn.Module = blocks[block_idx]
for attr in _SUFFIX_TO_ATTR_PATH[match.group(2)]:
target = getattr(target, attr)
return target
View on GitHub (pinned to 0b6a024f2f)
Solutions
- Match the adapter to a base transformer with at least as many blocks as it targets.
- Filter out or remap adapter entries whose block indices exceed len(transformer.blocks).
- Verify model config (number of transformer blocks) hasn't changed relative to the adapter's training config.
Example fix
// before lllite.apply_to(transformer_distilled) # 28 blocks, adapter targets block 30 // after lllite.apply_to(transformer_full) # 36 blocks, matches adapter
Defensive patterns
Strategy: validation
Validate before calling
max_block = max(int(re.search(r"blocks(\d+)", m["lllite_name"]).group(1)) for m in adapter_modules) assert max_block < len(transformer.blocks)
Type guard
def fits_transformer(names: list[str], transformer) -> bool:
return all(int(n.split("blocks")[1].split(".")[0] if "." in n else re.search(r"\d+", n).group()) < len(transformer.blocks) for n in names) Try / catch
try:
lllite.apply_to(transformer)
except ValueError as e:
if "has only" in str(e):
logger.error("Adapter targets a deeper transformer than loaded: %s", e)
raise Prevention
- Record the base model depth with the adapter and verify len(transformer.blocks) first.
- Filter adapter entries whose block index exceeds model depth at load time.
- Pin model versions in graph definitions.
When it happens
Trigger: apply_to(transformer) where an adapter name like 'blocks30.ff.net.0.proj' is applied to a transformer with e.g. 28 blocks — a shallower model than the adapter was trained on.
Common situations: Adapter trained on a deep (e.g. 36-block) Anima model applied to a distilled or smaller variant; changed num_blocks in model config after adapter training.
Related errors
- Unexpected cond image shape: {tuple(rgb_bchw_01.shape)} (exp
- Unexpected mask shape: {tuple(mask_b1hw_01.shape)} (expected
- LLLite target for '{m.lllite_name}' is {type(target).__name_
- LLLite module '{m.lllite_name}' was trained for in_features=
- Hidden size {params.hidden_size} must be divisible by num_he
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/117b94800a272c22.
Report an issue: GitHub.