invoke-ai/InvokeAI · info · NotAMatchError
directory looks like a full diffusers pipeline (has model_in
Error message
directory looks like a full diffusers pipeline (has model_index.json or transformer folder), not a standalone Qwen3 encoder
What it means
NotAMatchError raised in Qwen3Encoder_Qwen3Encoder_Config.from_model_on_disk (qwen3_encoder.py:300). The scanned directory is a full diffusers pipeline (it has model_index.json at root or a transformer/ subfolder), so it must be registered as a main pipeline model, not as a standalone Qwen3 text encoder. The guard prevents the Qwen3Encoder config from claiming whole pipelines.
Source
Thrown at invokeai/backend/model_manager/configs/qwen3_encoder.py:300
base: Literal[BaseModelType.Any] = Field(default=BaseModelType.Any)
type: Literal[ModelType.Qwen3Encoder] = Field(default=ModelType.Qwen3Encoder)
format: Literal[ModelFormat.Qwen3Encoder] = Field(default=ModelFormat.Qwen3Encoder)
cpu_only: bool | None = Field(default=None, description="Whether this model should run on CPU only")
variant: Qwen3VariantType = Field(description="Qwen3 model size variant (4B or 8B)")
@classmethod
def from_model_on_disk(cls, mod: ModelOnDisk, override_fields: dict[str, Any]) -> Self:
raise_if_not_dir(mod)
raise_for_override_fields(cls, override_fields)
# Exclude full pipeline models - these should be matched as main models, not just Qwen3 encoders.
# Full pipelines have model_index.json at root (diffusers format) or a transformer subfolder.
model_index_path = mod.path / "model_index.json"
transformer_path = mod.path / "transformer"
if model_index_path.exists() or transformer_path.exists():
raise NotAMatchError(
"directory looks like a full diffusers pipeline (has model_index.json or transformer folder), "
"not a standalone Qwen3 encoder"
)
# Check for text_encoder config - support both:
# 1. Full model structure: model_root/text_encoder/config.json
# 2. Standalone text_encoder download: model_root/config.json (when text_encoder subfolder is downloaded separately)
config_path_nested = mod.path / "text_encoder" / "config.json"
config_path_direct = mod.path / "config.json"
if config_path_nested.exists():
expected_config_path = config_path_nested
elif config_path_direct.exists():
# Standalone text_encoder downloads do not bundle tokenizer files. If we see tokenizer files at the
# root next to config.json, this is a complete causal LM (TextLLM), not a Qwen3 encoder subfolder.
tokenizer_files = ("tokenizer.json", "tokenizer.model", "tokenizer_config.json")
if any((mod.path / f).exists() for f in tokenizer_files):
raise NotAMatchError(View on GitHub (pinned to 0b6a024f2f)
Solutions
- Install the directory as a main pipeline model — InvokeAI should match it with the appropriate pipeline config.
- If you only need the encoder, download just the text_encoder/ subfolder into its own directory and scan that.
- Move the full pipeline out of the folder being scanned as an encoder candidate.
- If you believe this is a false positive, rename/remove a stray model_index.json or transformer/ dir that leaked into the encoder folder.
Example fix
// before models/z-image/ // full pipeline: model_index.json + transformer/ + text_encoder/ // after models/z-image/ installed as pipeline; models/z-image-text-encoder/ containing only text_encoder/ contents
Defensive patterns
Strategy: validation
Validate before calling
def is_full_pipeline(path) -> bool:
return (path / 'model_index.json').exists() or (path / 'transformer').is_dir() # install as main pipeline model Type guard
def is_standalone_encoder_dir(path) -> bool:
return not (path / 'model_index.json').exists() and not (path / 'transformer').exists() and ((path / 'text_encoder' / 'config.json').exists() or (path / 'config.json').exists()) Try / catch
if is_full_pipeline(model_dir):
install_as_pipeline(model_dir)
else:
try:
install_as_encoder(model_dir)
except NotAMatchError as e:
logger.warning('Encoder install failed: %s', e) Prevention
- Download only the text_encoder/ subfolder when you need a standalone encoder.
- Install full pipeline repos (model_index.json present) as main models.
- Never clone entire pipeline repos into encoder scan directories.
When it happens
Trigger: Running model scan/install on a directory containing model_index.json or a transformer/ subfolder while the Qwen3Encoder config's from_model_on_disk probes it.
Common situations: Pointing InvokeAI at a full HuggingFace pipeline checkout (e.g. a FLUX.2 or Z-Image repo root) and expecting only the encoder to be imported; downloading a whole repo with git clone instead of only the text_encoder subfolder.
Related errors
- directory looks like a complete causal LM (config.json and t
- directory is not a full FLUX.2 pipeline (no model_index.json
- unrecognized scheduler prediction_type {prediction_type}
- hidden size does not match a known Qwen3 variant
- state dict does not look like a Qwen3 model
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/873f75be62c3a03b.
Report an issue: GitHub.