invoke-ai/InvokeAI · error · NotAMatchError

missing text_encoder/ subfolder

Error message

missing text_encoder/ subfolder

What it means

Raised as a NotAMatchError by QwenVLEncoder_Diffusers_Config.from_model_on_disk when the candidate directory lacks a text_encoder/ subfolder. The diffusers-style standalone Qwen2.5-VL encoder layout requires text_encoder/ (with config.json and weights) and tokenizer/ subfolders; without text_encoder/ there is nothing to classify, so the matcher rejects the directory.

Source

Thrown at invokeai/backend/model_manager/configs/qwen_vl_encoder.py:90

    @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)

        # Reject anything that looks like a full pipeline (those are matched as Main models).
        if (mod.path / "model_index.json").exists() or (mod.path / "transformer").exists():
            raise NotAMatchError(
                "directory looks like a full diffusers pipeline (has model_index.json or transformer folder), "
                "not a standalone Qwen VL encoder"
            )

        text_encoder_dir = mod.path / "text_encoder"
        tokenizer_dir = mod.path / "tokenizer"

        if not text_encoder_dir.is_dir():
            raise NotAMatchError("missing text_encoder/ subfolder")
        if not tokenizer_dir.is_dir():
            raise NotAMatchError("missing tokenizer/ subfolder")

        config_path = text_encoder_dir / "config.json"
        if not config_path.is_file():
            raise NotAMatchError(f"missing {config_path}")

        try:
            with open(config_path, "r", encoding="utf-8") as f:
                cfg = json.load(f)
        except (OSError, json.JSONDecodeError) as e:
            raise NotAMatchError(f"could not read text_encoder/config.json: {e}") from e

        class_name = cfg.get("_class_name")
        architectures = cfg.get("architectures") or []
        candidates = {class_name, *architectures} - {None}

        if not candidates & _RECOGNIZED_TEXT_ENCODER_CLASSES:

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Verify the layout: the directory must contain text_encoder/ (with config.json + model.safetensors) and tokenizer/ subfolders.
  2. Re-download with `huggingface-cli download <repo>` ensuring text_encoder/ and tokenizer/ are fetched, then rescan in InvokeAI.
  3. Move or rename the subfolder to exactly `text_encoder` (check for typos and extra nesting levels).
  4. If the model is a single .safetensors file, let it be matched by the QwenVLEncoder_Checkpoint config instead of forcing the diffusers-folder type.

Example fix

// before (missing text_encoder/)
my-encoder/
  tokenizer/
  encoder_files/          # wrong name / nesting

// after
my-encoder/
  text_encoder/
    config.json
    model.safetensors
  tokenizer/
    tokenizer_config.json
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path

def has_standalone_qwenvl_layout(root: Path) -> bool:
    return (
        (root / "text_encoder").is_dir()
        and (root / "tokenizer").is_dir()
        and (root / "text_encoder" / "config.json").is_file()
    )

assert has_standalone_qwenvl_layout(Path("/path/to/model")), "expected text_encoder/ + tokenizer/ subfolders"

Type guard

from pathlib import Path

def is_diffusers_encoder_layout(p: Path) -> bool:
    te, tok = p / "text_encoder", p / "tokenizer"
    return te.is_dir() and tok.is_dir() and (te / "config.json").is_file()

Try / catch

try:
    invokeai_model_manager.probe(model_dir)
except NotAMatchError as e:
    if "missing text_encoder/ subfolder" in str(e):
        fetch_missing_subfolders_from_hub(repo_id, needed=["text_encoder", "tokenizer"], dest=model_dir)
    else:
        raise

Prevention

When it happens

Trigger: Importing a directory that is neither a full pipeline nor the expected layout — e.g. a folder containing only tokenizer/, only processor/, only a bare safetensors file at the root, or an empty/near-empty download directory — while the QwenVLEncoder_Diffusers matcher runs.

Common situations: Downloading only part of a HuggingFace repo; extracting an archive that nests files one level deeper than expected; manually renaming subfolders (e.g. 'text-encoder' or 'text_encoder' placed inside another folder); pointing at the repo root of an encoder repo whose weights live in a differently named subfolder.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/2c869b7515249ab7. Report an issue: GitHub.