{"record":{"id":"097d3d13b135cd59","repo":"invoke-ai/InvokeAI","slug":"directory-is-not-a-full-flux-2-pipeline-no-model","errorCode":null,"errorMessage":"directory is not a full FLUX.2 pipeline (no model_index.json and no transformer/ subfolder); a loose transformer-only checkout cannot be used as a FLUX.2 main model","messagePattern":"directory is not a full FLUX\\.2 pipeline \\(no model_index\\.json and no transformer/ subfolder\\); a loose transformer-only checkout cannot be used as a FLUX\\.2 main model","errorType":"exception","errorClass":"NotAMatchError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/model_manager/configs/main.py","lineNumber":1012,"sourceCode":"    variant: Flux2VariantType = Field()\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        # A FLUX.2 *main* model is a full diffusers pipeline: a `model_index.json` at\n        # the root, or at least the transformer packaged as a `transformer/` subfolder.\n        # A loose transformer-only checkout — just the contents of `transformer/`, with\n        # a root `config.json` whose `_class_name` is `Flux2Transformer2DModel` — is NOT\n        # a usable main model: the loader unconditionally appends `vae/` / `text_encoder/`\n        # subfolders that don't exist and fails with an OSError mid-queue. Reject that\n        # layout here so it falls through to a non-main classification instead of\n        # registering as a broken pipeline. (The standalone `transformer/` still matches\n        # via the pipeline layout below when it ships inside a full folder.)\n        if not (mod.path / \"model_index.json\").exists() and not (mod.path / \"transformer\").exists():\n            raise NotAMatchError(\n                \"directory is not a full FLUX.2 pipeline (no model_index.json and no transformer/ subfolder); \"\n                \"a loose transformer-only checkout cannot be used as a FLUX.2 main model\"\n            )\n\n        # Check for FLUX.2-specific pipeline class names\n        raise_for_class_name(\n            common_config_paths(mod.path),\n            {\n                \"Flux2KleinPipeline\",\n                \"Flux2Pipeline\",\n                \"Flux2Transformer2DModel\",\n            },\n        )\n\n        # Reject SDNQ-quantized pipelines so the SDNQ-specific config matches them instead.\n        # Without this both configs accept the same folder and identification can latch onto\n        # the wrong one (the plain diffusers loader would then mis-read packed uint8 weights\n        # as bf16 and crash with size-mismatch errors at first inference).","sourceCodeStart":994,"sourceCodeEnd":1030,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/model_manager/configs/main.py#L994-L1030","documentation":"from_model_on_disk for the FLUX.2 diffusers config rejects any directory that lacks both `model_index.json` and a `transformer/` subfolder. Without them the directory is not a complete FLUX.2 pipeline; the loader would append `vae/` and `text_encoder/` subpaths that don't exist and crash with an OSError mid-generation. Raising NotAMatchError makes the folder fall through to a non-main classification instead of registering as a broken pipeline.","triggerScenarios":"Scanning/installing a model folder where `model_index.json` is absent AND no `transformer/` entry exists, during FLUX.2 main-model identification via from_model_on_disk.","commonSituations":"Pointing InvokeAI at a bare diffusers `transformer/` checkout (e.g. only cloned the transformer subfolder of a FLUX.2 repo), a partial/interrupted download that dropped top-level files, or a folder holding only VAE or text-encoder components.","solutions":["Use the full FLUX.2 pipeline repo/folder containing `model_index.json` plus `vae/`, `text_encoder/`, and `transformer/` subfolders.","If you only have the transformer, either place it inside a complete pipeline folder (the standalone `transformer/` then matches via the pipeline layout) or use a checkpoint/single-file import path.","Re-download if files were lost during transfer; verify `model_index.json` exists at the folder root before scanning."],"exampleFix":"// before (loose checkout)\nmodels/flux.2/transformer/config.json\n// after (full pipeline)\nmodels/flux.2/model_index.json\nmodels/flux.2/transformer/config.json\nmodels/flux.2/vae/...\nmodels/flux.2/text_encoder/...","handlingStrategy":"validation","validationCode":"from pathlib import Path\n\ndef validate_flux2_pipeline(folder: Path) -> None:\n    if not (folder / \"model_index.json\").exists() and not (folder / \"transformer\").exists():\n        raise ValueError(f\"{folder} is not a full FLUX.2 pipeline: missing model_index.json and transformer/\")","typeGuard":"def is_full_flux2_pipeline(folder: Path) -> bool:\n    return (folder / \"model_index.json\").is_file() or (folder / \"transformer\").exists()","tryCatchPattern":"try:\n    cfg = Main_Diffusers_Flux2_Config.from_model_on_disk(mod)\nexcept NotAMatchError:\n    # not a complete pipeline; classify as non-main or guide user to re-download\n    cfg = None","preventionTips":["Always clone/download the entire FLUX.2 repo (model_index.json + vae/ + text_encoder/ + transformer/).","Verify model_index.json exists at the folder root before adding the model to InvokeAI.","Avoid pointing the models directory at a bare transformer-only checkout."],"tags":["model-identification","flux","pipeline-layout","diffusers"],"backgroundTag":"incomplete-model-directory","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}