{"record":{"id":"4871ab53c8a9b705","repo":"invoke-ai/InvokeAI","slug":"directory-looks-like-a-full-diffusers-pipeline-ha-4871ab","errorCode":null,"errorMessage":"directory looks like a full diffusers pipeline (has model_index.json or transformer folder), not a standalone Qwen VL encoder","messagePattern":"directory looks like a full diffusers pipeline \\(has model_index\\.json or transformer folder\\), not a standalone Qwen VL encoder","errorType":"validation","errorClass":"NotAMatchError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/model_manager/configs/qwen_vl_encoder.py","lineNumber":81,"sourceCode":"                preprocessor_config.json\n\n    This lets users avoid downloading the full ~40 GB Qwen Image diffusers pipeline\n    when they only need the Qwen2.5-VL encoder for use with a GGUF transformer.\n    \"\"\"\n\n    base: Literal[BaseModelType.Any] = Field(default=BaseModelType.Any)\n    type: Literal[ModelType.QwenVLEncoder] = Field(default=ModelType.QwenVLEncoder)\n    format: Literal[ModelFormat.QwenVLEncoder] = Field(default=ModelFormat.QwenVLEncoder)\n\n    @classmethod\n    def from_model_on_disk(cls, mod: ModelOnDisk, override_fields: dict[str, Any]) -> Self:\n        raise_if_not_dir(mod)\n\n        raise_for_override_fields(cls, override_fields)\n\n        # Reject anything that looks like a full pipeline (those are matched as Main models).\n        if (mod.path / \"model_index.json\").exists() or (mod.path / \"transformer\").exists():\n            raise NotAMatchError(\n                \"directory looks like a full diffusers pipeline (has model_index.json or transformer folder), \"\n                \"not a standalone Qwen VL encoder\"\n            )\n\n        text_encoder_dir = mod.path / \"text_encoder\"\n        tokenizer_dir = mod.path / \"tokenizer\"\n\n        if not text_encoder_dir.is_dir():\n            raise NotAMatchError(\"missing text_encoder/ subfolder\")\n        if not tokenizer_dir.is_dir():\n            raise NotAMatchError(\"missing tokenizer/ subfolder\")\n\n        config_path = text_encoder_dir / \"config.json\"\n        if not config_path.is_file():\n            raise NotAMatchError(f\"missing {config_path}\")\n\n        try:\n            with open(config_path, \"r\", encoding=\"utf-8\") as f:","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/model_manager/configs/qwen_vl_encoder.py#L63-L99","documentation":"Raised as a NotAMatchError by QwenVLEncoder_Diffusers_Config.from_model_on_disk when the candidate directory contains model_index.json or a transformer/ folder, marking it as a full diffusers pipeline. InvokeAI deliberately refuses to classify such directories as a standalone Qwen VL encoder because full pipelines (e.g. the ~40GB Qwen Image repo) must be registered as Main models, not just their text encoder.","triggerScenarios":"Pointing the model import/probe at the root of a full diffusers pipeline directory (containing model_index.json, transformer/, text_encoder/, tokenizer/) so the QwenVLEncoder_Diffusers matcher runs first and rejects it.","commonSituations":"Downloading the whole Qwen Image or similar repo and adding its top-level folder; nesting an encoder inside a pipeline checkout; specifying the parent directory in InvokeAI's model-add UI instead of the text_encoder subtree.","solutions":["Register the directory as a Main model instead — InvokeAI matches full pipelines through the main-model path.","If you only want the encoder, extract/download a standalone layout with just text_encoder/ and tokenizer/ subfolders (no model_index.json, no transformer/).","Copy text_encoder/ and tokenizer/ out into a new folder without model_index.json or transformer/, then import that.","Use a HF repo that ships only the encoder components rather than the consolidated pipeline."],"exampleFix":"// before (rejected: pipeline root)\nqwen-image/\n  model_index.json\n  transformer/\n  text_encoder/\n\n// after (standalone encoder layout)\nqwen-vl-encoder/\n  text_encoder/\n    config.json\n    model.safetensors\n  tokenizer/\n    tokenizer_config.json","handlingStrategy":"validation","validationCode":"from pathlib import Path\n\ndef is_full_pipeline_dir(root: Path) -> bool:\n    return (root / \"model_index.json\").exists() or (root / \"transformer\").exists()\n\n# before import:\nroot = Path(\"/path/to/model\")\nif is_full_pipeline_dir(root):\n    print(\"Register as a Main model, not a standalone Qwen VL encoder\")","typeGuard":"from pathlib import Path\n\ndef is_standalone_encoder_dir(p: Path) -> bool:\n    return p.is_dir() and not (p / \"model_index.json\").exists() and not (p / \"transformer\").exists()","tryCatchPattern":"try:\n    invokeai_model_manager.probe(model_dir)\nexcept NotAMatchError as e:\n    if \"full diffusers pipeline\" in str(e):\n        add_model_as_main(model_dir)  # register the pipeline via the main-model path instead\n    else:\n        raise","preventionTips":["If the folder contains model_index.json or transformer/, add it as a Main model — InvokeAI handles the encoder internally.","For encoder-only use, build a standalone folder with just text_encoder/ and tokenizer/.","Never point the encoder import at a full pipeline checkout root.","Check for model_index.json with `ls` before importing a directory."],"tags":["invokeai","model-import","diffusers","pipeline","not-a-match"],"backgroundTag":"wrong-model-directory-layout","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}