{"record":{"id":"81fdcf3097041350","repo":"invoke-ai/InvokeAI","slug":"expected-qwen3encoder-sdnq-config-or-qwen3encoder","errorCode":null,"errorMessage":"Expected Qwen3Encoder_SDNQ_Config or Qwen3Encoder_SDNQ_Folder_Config, got {type(config).__name__}.","messagePattern":"Expected Qwen3Encoder_SDNQ_Config or Qwen3Encoder_SDNQ_Folder_Config, got (.+?)\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/model_manager/load/model_loaders/z_image.py","lineNumber":1501,"sourceCode":"        \"\"\"Load tokenizer with local_files_only fallback for offline support.\"\"\"\n        try:\n            return AutoTokenizer.from_pretrained(self.DEFAULT_TOKENIZER_SOURCE, local_files_only=True)\n        except OSError:\n            return AutoTokenizer.from_pretrained(self.DEFAULT_TOKENIZER_SOURCE)\n\n    def _load_from_sdnq(\n        self,\n        config: AnyModelConfig,\n    ) -> AnyModel:\n        from transformers import Qwen3Config, Qwen3ForCausalLM\n\n        from invokeai.backend.quantization.sdnq.sdnq_tensor import SDNQTensor\n        from invokeai.backend.util.logging import InvokeAILogger\n\n        logger = InvokeAILogger.get_logger(self.__class__.__name__)\n\n        if not isinstance(config, (Qwen3Encoder_SDNQ_Config, Qwen3Encoder_SDNQ_Folder_Config)):\n            raise TypeError(\n                f\"Expected Qwen3Encoder_SDNQ_Config or Qwen3Encoder_SDNQ_Folder_Config, got {type(config).__name__}.\"\n            )\n        model_path = Path(config.path)\n\n        # Determine safe dtype based on target device capabilities\n        target_device = TorchDevice.choose_torch_device()\n        compute_dtype = TorchDevice.choose_bfloat16_safe_dtype(target_device)\n\n        # Load the SDNQ state dict - this returns SDNQTensor wrappers (on CPU)\n        sd = sdnq_sd_loader(model_path, compute_dtype=compute_dtype)\n\n        # Determine Qwen model configuration from state dict\n        layer_count = 0\n        for key in sd.keys():\n            if isinstance(key, str) and key.startswith(\"model.layers.\"):\n                parts = key.split(\".\")\n                if len(parts) > 2:\n                    try:","sourceCodeStart":1483,"sourceCodeEnd":1519,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/model_manager/load/model_loaders/z_image.py#L1483-L1519","documentation":"_load_from_sdnq re-validates its config argument with a isinstance check and raises TypeError if the config is not Qwen3Encoder_SDNQ_Config or Qwen3Encoder_SDNQ_Folder_Config. This is a defensive guard reached when the dispatch in _load_model is bypassed (direct call) or the config type changed between dispatch and call.","triggerScenarios":"Calling _load_from_sdnq directly with some other config object; refactored/forked code constructing configs that pass an earlier check but not this one; mocking in tests that substitutes a generic config.","commonSituations":"Plugin or custom-node code calling the loader's private method directly; subclasses overriding _load_model without preserving the config contract; stale pickled/serialized config objects of an older class version.","solutions":["Pass a Qwen3Encoder_SDNQ_Config or Qwen3Encoder_SDNQ_Folder_Config instance (construct from the model path with the correct class).","Do not call _load_from_sdnq directly; go through _load_model which performs the correct dispatch.","Update any custom config classes to inherit from the supported SDNQ config types.","Fix tests/mocks that replace the config with a generic object."],"exampleFix":"// before\nloader._load_from_sdnq(ModelConfigBase(path=p))\n// after\ncfg = Qwen3Encoder_SDNQ_Folder_Config(path=p)\nloader._load_from_sdnq(cfg)","handlingStrategy":"type-guard","validationCode":"cfg_t = type(config).__name__\nassert cfg_t in (\"Qwen3Encoder_SDNQ_Config\", \"Qwen3Encoder_SDNQ_Folder_Config\"), \\\n    f\"bad config for _load_from_sdnq: {cfg_t}\"","typeGuard":"def is_sdnq_config(config: object) -> bool:\n    return hasattr(config, \"path\") and type(config).__name__ in (\n        \"Qwen3Encoder_SDNQ_Config\", \"Qwen3Encoder_SDNQ_Folder_Config\")","tryCatchPattern":"try:\n    model = loader._load_model(cfg, SubModelType.TextEncoder)\nexcept TypeError as e:\n    if \"Expected Qwen3Encoder_SDNQ\" in str(e):\n        cfg = rebuild_config_as_sdnq(cfg.path)\n        model = loader._load_model(cfg, SubModelType.TextEncoder)\n    else:\n        raise","preventionTips":["Never call private loader methods directly; use _load_model/public load service.","Keep config classes stable across refactors; update serialized records after class renames.","Use the real config classes (not mocks) in integration paths.","Add isinstance assertions at loader boundaries in custom pipelines."],"tags":["typeerror","sdnq","config","type-mismatch"],"backgroundTag":"unsupported-model-config-type","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}