{"record":{"id":"fe69077fd28ec5eb","repo":"invoke-ai/InvokeAI","slug":"unable-to-load-config-file-s-posixpath-confi","errorCode":null,"errorMessage":"unable to load config file(s): {{PosixPath('{config_path_nested}'): 'file does not exist'}}","messagePattern":"unable to load config file\\(s\\): (.+?)'\\): 'file does not exist'\\}\\}","errorType":"exception","errorClass":"NotAMatchError","httpStatus":null,"severity":"warning","filePath":"invokeai/backend/model_manager/configs/qwen3_encoder.py","lineNumber":324,"sourceCode":"        # 1. Full model structure: model_root/text_encoder/config.json\n        # 2. Standalone text_encoder download: model_root/config.json (when text_encoder subfolder is downloaded separately)\n        config_path_nested = mod.path / \"text_encoder\" / \"config.json\"\n        config_path_direct = mod.path / \"config.json\"\n\n        if config_path_nested.exists():\n            expected_config_path = config_path_nested\n        elif config_path_direct.exists():\n            # Standalone text_encoder downloads do not bundle tokenizer files. If we see tokenizer files at the\n            # root next to config.json, this is a complete causal LM (TextLLM), not a Qwen3 encoder subfolder.\n            tokenizer_files = (\"tokenizer.json\", \"tokenizer.model\", \"tokenizer_config.json\")\n            if any((mod.path / f).exists() for f in tokenizer_files):\n                raise NotAMatchError(\n                    \"directory looks like a complete causal LM (config.json and tokenizer files at root), \"\n                    \"not a standalone Qwen3 encoder\"\n                )\n            expected_config_path = config_path_direct\n        else:\n            raise NotAMatchError(\n                f\"unable to load config file(s): {{PosixPath('{config_path_nested}'): 'file does not exist'}}\"\n            )\n\n        # Qwen3 uses Qwen2VLForConditionalGeneration or similar\n        raise_for_class_name(expected_config_path, _QWEN3_ENCODER_ARCHITECTURES)\n\n        # Reject SDNQ-quantized encoders so Qwen3Encoder_SDNQ_Folder_Config matches them instead.\n        # A real SDNQ Qwen3 encoder has the same Qwen3 config class name as an unquantized one, so\n        # without this guard both configs accept the folder — and since they share the Qwen3Encoder\n        # type, the factory tiebreak is non-deterministic. If it picked this (unquantized) config,\n        # the non-SDNQ loader would then mis-read the packed uint8 weights.\n        cls._reject_if_sdnq_quantized(mod)\n\n        # Determine variant from config.json hidden_size\n        variant = cls._get_variant_from_config(expected_config_path)\n\n        return cls(variant=variant, **override_fields)\n","sourceCodeStart":306,"sourceCodeEnd":342,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/model_manager/configs/qwen3_encoder.py#L306-L342","documentation":"NotAMatchError raised in Qwen3Encoder_Qwen3Encoder_Config.from_model_on_disk (qwen3_encoder.py:324) when neither text_encoder/config.json nor config.json exists in the scanned directory. The message is phrased as a config-load failure naming the nested path, but its meaning is simply: this directory does not contain a Qwen3 encoder config.json, so this config does not match.","triggerScenarios":"from_model_on_disk on a directory where both mod.path/'text_encoder'/'config.json' and mod.path/'config.json' are missing — e.g. an empty folder, a folder with only weights and no config, or weights placed at the wrong nesting level.","commonSituations":"Interrupted HuggingFace downloads that skipped config.json; copying only *.safetensors files; scanning a GGUF directory (no config.json at all); pointing the scan at the model repo root when config.json lives in a differently named subfolder.","solutions":["Ensure the directory contains config.json either at the root or under text_encoder/; re-download it from the model repo.","Check for .no_exist / partial-download markers from huggingface_hub and retry the download.","If this is a GGUF model, it will never have config.json here — install it via the GGUF flow instead.","Point the scanner at the folder that actually holds the encoder config."],"exampleFix":"// before\nmodels/qwen3-encoder/  // only model.safetensors\n// after\nmodels/qwen3-encoder/  // config.json + model.safetensors (config.json re-downloaded from the repo)","handlingStrategy":"validation","validationCode":"def has_encoder_config(path) -> bool:\n    return (path / 'text_encoder' / 'config.json').exists() or (path / 'config.json').exists()\n# call before install; if False, re-download config.json from the model repo","typeGuard":"def encoder_config_path(path):\n    nested = path / 'text_encoder' / 'config.json'\n    direct = path / 'config.json'\n    if nested.exists():\n        return nested\n    if direct.exists():\n        return direct\n    return None  # None means the Qwen3Encoder config will reject it","tryCatchPattern":"cfg = encoder_config_path(model_dir)\nif cfg is None:\n    raise FileNotFoundError(f'No config.json under {model_dir}; re-download from the model repo')\ntry:\n    register_model(model_dir, model_type='Qwen3Encoder')\nexcept NotAMatchError as e:\n    logger.warning('Qwen3Encoder config rejected folder: %s', e)","preventionTips":["Always download config.json together with weight files (avoid *.safetensors-only downloads).","After download, verify config.json exists before registering the model.","Check for interrupted huggingface_hub snapshots (.incomplete / .no_exist markers)."],"tags":["missing-file","config-json","model-identification","qwen3"],"backgroundTag":"missing-config-file","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}