hiyouga/LlamaFactory · error · ValueError
Plugin {self.name!r} is not registered under {cls.__name__}.
Error message
Plugin {self.name!r} is not registered under {cls.__name__}. What it means
BasePlugin._resolve (src/llamafactory/v1/utils/plugin.py:102) looks up the plugin instance's name in its family's registry (cls._registry), a per-subclass dict populated only when the implementing module defining the @Plugin("name").register() decorator is imported. If the name is absent — misspelled, never registered, or its defining module never imported/installed — resolution fails with this ValueError. Because BasePlugin routes both __call__ and __getattr__ through _resolve, the error can surface on the first attribute access or call of a plugin object, not just at construction.
Source
Thrown at src/llamafactory/v1/utils/plugin.py:102
f"{cls.__name__} config must be a mapping or {params_cls.__name__}, got {type(config).__name__}."
)
known = {item.name for item in fields(params_cls)}
unknown = set(values) - known
if unknown:
raise ValueError(
f"Unknown params for {cls.__name__}.{params_cls.__name__}: {sorted(unknown)}. "
f"Expected: {sorted(known)}"
)
return params_cls(**values)
def _resolve(self) -> Any:
cls = type(self)
if self.name is None:
raise ValueError(f"{cls.__name__} must be constructed with a name.")
if self.name not in cls._registry:
raise ValueError(f"Plugin {self.name!r} is not registered under {cls.__name__}.")
return cls._registry[self.name]
def __call__(self, *args, **kwargs) -> Any:
return self._resolve()(*args, **kwargs)
def __getattr__(self, attr: str) -> Any:
return getattr(self._resolve(), attr)
View on GitHub (pinned to f28afaf635)
Solutions
- Check the exact registered names for the family: python -c "from llamafactory.v1.plugins.model_plugins.peft import PeftPlugin; print(PeftPlugin._registry)" (substitute the family you use) and correct the name in your config/code to one of those keys.
- Ensure the module that registers the plugin is imported before resolution — for built-ins, import the family's package (e.g. llamafactory.v1.plugins.trainer_plugins.batching) or trigger the package's __init__ import path; for custom plugins, import your module before first use.
- If using an optional kernel plugin (liger_kernel, npu_*, cuda_fused_moe), install the required dependency (e.g. liger-kernel) and confirm the ops module import succeeds — a swallowed ImportError earlier can leave the name unregistered.
- When upgrading LlamaFactory, grep the new version's @XxxPlugin("...").register() decorators for the family to see whether the name was renamed or dropped, then update your config.
Example fix
# before — name typo, nothing registered under "dynamic"
from llamafactory.v1.plugins.trainer_plugins.batching import BatchingPlugin
strategy = BatchingPlugin("dynamic")
batch = strategy(...)
# after — use an actually registered name
strategy = BatchingPlugin("dynamic_batching")
batch = strategy(...) Defensive patterns
Strategy: validation
Validate before calling
def plugin_name_exists(plugin_cls, name: str) -> bool:
"""True when name is registered in this plugin family's registry."""
return name in plugin_cls._registry
# usage
if not plugin_name_exists(BatchingPlugin, requested_name):
raise SystemExit(
f"Unknown plugin {requested_name!r}; registered: {sorted(BatchingPlugin._registry)}"
) Type guard
def is_registered_plugin(plugin_cls, name: str) -> bool:
"""Narrow plugin names to those actually registered under plugin_cls."""
return isinstance(name, str) and name in plugin_cls._registry Try / catch
from llamafactory.v1.utils.plugin import BasePlugin
try:
result = plugin(*args)
except ValueError as e:
if "is not registered under" in str(e):
raise SystemExit(
f"{e}; available: {sorted(type(plugin)._registry)}"
) from None
raise Prevention
- Import the plugin family's package (which triggers all @register() decorators) before constructing or resolving any plugin.
- Derive plugin names from plugin_cls._registry (or an explicit allowlist) rather than free-typed strings in YAML.
- For optional kernel plugins, verify the optional dependency imports cleanly at startup — a failed import silently skips registration.
- On upgrades, re-run a smoke check that prints sorted(FamilyPlugin._registry) and confirm every name in your config is present.
When it happens
Trigger: Constructing a plugin family member with a name that has no @register() decorator in the family's registry, e.g. PeftPlugin("lor") (typo for "lora"), BatchingPlugin("dynamic") (real names: padding_free, dynamic_batching, dynamic_padding_free), or QuantizationPlugin("gptq") when only auto/bnb are registered. Also triggered when the plugin implementation lives in a module that was never imported (e.g. a KernelPlugin op in an optional NPU/CUDA kernels file that the import path skipped), or when code uses a fresh plugin family subclass whose registrations were never executed.
Common situations: Typo in a config string selecting a plugin (peft: "lora" misspelled, batching name mismatch with the registered set); optional kernels (liger_kernel, npu_fused_rope, cuda_fused_moe) not registered because the optional dependency or hardware-specific ops module was not imported; version upgrades that renamed or removed a registered name; custom plugins registered only at import time in a module the entry path does not import; copy-pasting a plugin name from v0 docs into a v1 (USE_V1=1) run.
Related errors
- Unknown params for {cls.__name__}.{params_cls.__name__}: {so
- KTransformers uses LLaMA-Factory's `disable_gradient_checkpo
- KTransformers supplies its checkpoint context; remove `gradi
- Disable FSDP activation checkpointing when using KTransforme
- KTransformers thin integration currently supports LoRA finet
AI-assisted analysis of hiyouga/LlamaFactory@f28afaf635 (2026-08-14).
Data as JSON: /api/errors/7973249136d4c43b.
Report an issue: GitHub.