invoke-ai/InvokeAI · error · NotAMatchError
directory looks like a full diffusers pipeline, not a standa
Error message
directory looks like a full diffusers pipeline, not a standalone Gemma2 encoder
What it means
After config.json exists, the prober rejects directories that also contain model_index.json at the root, since that marks a full diffusers pipeline (UNet+VAE+encoders together) rather than the standalone Gemma2 encoder InvokeAI requires for PiD caption projection. Probing such a pipeline raises NotAMatchError.
Source
Thrown at invokeai/backend/model_manager/configs/gemma2_encoder.py:67
"""
base: Literal[BaseModelType.Any] = Field(default=BaseModelType.Any)
type: Literal[ModelType.Gemma2Encoder] = Field(default=ModelType.Gemma2Encoder)
format: Literal[ModelFormat.Gemma2Encoder] = Field(default=ModelFormat.Gemma2Encoder)
cpu_only: bool | None = Field(default=None, description="Whether this model should run on CPU only")
@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)
config_path = mod.path / "config.json"
if not config_path.exists():
raise NotAMatchError(f"missing config.json at {config_path}")
# Reject full diffusers pipelines (they have model_index.json at root).
if (mod.path / "model_index.json").exists():
raise NotAMatchError("directory looks like a full diffusers pipeline, not a standalone Gemma2 encoder")
# Architecture marker is the canonical signal.
raise_for_class_name(config_path, {"Gemma2ForCausalLM"})
# Only Gemma-2-2b (2304-dim hidden state) is compatible with PiD's fixed caption projection.
# Reject 9B/27B variants here so they are not offered as compatible encoders and then fail with
# a matrix-shape error deep inside PiD inference.
hidden_size = get_config_dict_or_raise(config_path).get("hidden_size")
if hidden_size != _PID_GEMMA_HIDDEN_SIZE:
raise NotAMatchError(
f"Gemma2 hidden_size {hidden_size} is incompatible with PiD, which requires "
f"{_PID_GEMMA_HIDDEN_SIZE} (Gemma-2-2b); 9B/27B variants are not supported."
)
# Sanity check that tokenizer files live alongside the model (PiD calls
# AutoTokenizer.from_pretrained on the same directory).
if not any((mod.path / f).exists() for f in ("tokenizer.json", "tokenizer.model")):
raise NotAMatchError("directory does not contain Gemma2 tokenizer files (tokenizer.json/tokenizer.model)")View on GitHub (pinned to 0b6a024f2f)
Solutions
- Import only the text_encoder/ subdirectory of the pipeline, not the repo root
- Remove model_index.json only if you truly isolated the encoder files into their own directory (otherwise keep the pipeline elsewhere)
- Download the standalone Gemma2 model and import its top-level folder directly
- Keep full pipelines outside InvokeAI's models directory to avoid component mis-probing
Example fix
// before
install_model("/models/gemma-2-2b-it") # full pipeline: has model_index.json
// after
install_model("/models/gemma-2-2b-it/text_encoder") # standalone encoder dir Defensive patterns
Strategy: validation
Validate before calling
import pathlib
def is_full_diffusers_pipeline(path: str) -> bool:
p = pathlib.Path(path)
return (p / "model_index.json").exists()
def encoder_import_path(path: str) -> str:
p = pathlib.Path(path)
return str(p / "text_encoder") if is_full_diffusers_pipeline(str(p)) else str(p) Try / catch
try:
config = probe(mod)
except NotAMatchError as e:
if "full diffusers pipeline" in str(e):
encoder = pathlib.Path(mod.path) / "text_encoder"
config = probe(encoder)
else:
raise Prevention
- Never import full pipeline snapshots as single models
- Point at the text_encoder subdirectory of pipelines
- Keep full pipelines outside the InvokeAI models directory
- Check for model_index.json before import to detect pipelines
When it happens
Trigger: from_model_on_disk pointed at a downloaded diffusers repo root (e.g. a full pipeline snapshot with model_index.json) instead of the text_encoder subfolder; or copying the whole HF snapshot into the models directory.
Common situations: Downloading gemma-2-2b-it as a full pipeline snapshot and importing the whole folder; pointing InvokeAI at the repo root rather than the encoder component directory.
Related errors
- missing config.json at {config_path}
- state dict has Anima ControlNet-LLLite keys but no lllite_co
- state dict does not look like an Anima ControlNet-LLLite mod
- File extension {path.suffix} is not a recognized model forma
- Directory contains more than {_MAX_FILES_IN_MODEL_DIR} files
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/d618259877a5b16e.
Report an issue: GitHub.