invoke-ai/InvokeAI · error · NotAMatchError
state dict does not look like a single-file Qwen3-VL encoder
Error message
state dict does not look like a single-file Qwen3-VL encoder
What it means
Raised as a NotAMatchError by Qwen3VLEncoder_Checkpoint_Config.from_model_on_disk when a .safetensors file loads but _is_qwen3_vl_encoder_state_dict() returns False — i.e. the key layout does not contain both a language-model decoder (keys with '.layers.' and 'model.' prefix) and a Qwen3-VL visual tower (keys starting with 'visual.', 'model.visual.', or containing '.visual.'). The visual tower is what distinguishes Qwen3-VL from the text-only Qwen3 encoder, so a text-only checkpoint is rejected.
Source
Thrown at invokeai/backend/model_manager/configs/qwen3_vl_encoder.py:192
"""
base: Literal[BaseModelType.Any] = Field(default=BaseModelType.Any)
type: Literal[ModelType.Qwen3VLEncoder] = Field(default=ModelType.Qwen3VLEncoder)
format: Literal[ModelFormat.Checkpoint] = Field(default=ModelFormat.Checkpoint)
cpu_only: bool | None = Field(default=None, description="Whether this model should run on CPU only")
@classmethod
def from_model_on_disk(cls, mod: ModelOnDisk, override_fields: dict[str, Any]) -> Self:
raise_if_not_file(mod)
raise_for_override_fields(cls, override_fields)
if mod.path.suffix.lower() != ".safetensors":
raise NotAMatchError(f"expected a .safetensors file, got {mod.path.suffix or '(no suffix)'}")
state_dict = mod.load_state_dict()
if not _is_qwen3_vl_encoder_state_dict(state_dict):
raise NotAMatchError("state dict does not look like a single-file Qwen3-VL encoder")
_validate_krea2_qwen3_vl_checkpoint_shape(state_dict)
return cls(**override_fields)
View on GitHub (pinned to 0b6a024f2f)
Solutions
- Inspect keys with `safetensors.safe_open(path).keys()` and confirm both language-model layer keys and visual-tower keys exist.
- Download the correct single-file Qwen3-VL checkpoint (e.g. a qwen3vl_4b_* safetensors that includes the vision tower).
- If you have a text-only Qwen3 encoder, let it match the text-only Qwen3Encoder config instead of forcing the Qwen3-VL checkpoint type.
- Re-export the checkpoint preserving original visual.* key names; restore missing vision-tower weights from the base repo.
Example fix
// before: text-only checkpoint -> rejected keys: ['model.embed_tokens.weight', 'model.layers.0...'] # no visual.* // after: correct Qwen3-VL checkpoint keys: ['model.layers.35...', 'visual.patch_embed.proj.weight', ...]
Defensive patterns
Strategy: validation
Validate before calling
from safetensors import safe_open
def looks_like_qwen3vl_checkpoint(path) -> bool:
with safe_open(str(path), framework="pt", device="cpu") as f:
keys = list(f.keys())
has_text = any(".layers." in k and ("model." in k or k.startswith("layers.")) for k in keys)
has_visual = any(k.startswith(("visual.", "model.visual.")) or ".visual." in k for k in keys)
return has_text and has_visual Type guard
def is_qwen3vl_state_dict(keys: list[str]) -> bool:
has_text_decoder = any(".layers." in k and ("model." in k or k.startswith("layers.")) for k in keys)
has_visual_tower = any(k.startswith(("visual.", "model.visual.")) or ".visual." in k for k in keys)
return has_text_decoder and has_visual_tower Try / catch
try:
invokeai_model_manager.probe(file_path)
except NotAMatchError as e:
if "does not look like a single-file Qwen3-VL encoder" in str(e):
# likely a text-only Qwen3 encoder or wrong checkpoint; inspect keys and re-source the file
inspect_and_relocate_checkpoint(file_path)
else:
raise Prevention
- Download checkpoints from the official qwen3vl_4b safetensors releases, not ad-hoc re-exports.
- Inspect safetensors headers (keys only) before importing large files to confirm visual.* keys exist.
- Don't prune or rename keys when converting checkpoints between formats.
- Keep text-only Qwen3 encoders and Qwen3-VL checkpoints clearly separated by filename.
When it happens
Trigger: Importing a single .safetensors file that is a text-only Qwen3 encoder (Z-Image / FLUX.2 Klein), a stripped/comfied checkpoint with renamed or pruned vision keys, or a diffusers-format tensor bundle whose keys use a naming scheme with no visual.* / .visual.* entries.
Common situations: Grabbing the wrong companion file (text-only qwen3 encoder instead of qwen3_vl_4b); a checkpoint re-exported with keys stripped of the vision tower; custom merges that rename visual.* keys; using a partial checkpoint containing only language-model layers.
Related errors
- standalone Qwen3-VL encoder directory does not contain token
- expected a .safetensors file, got {mod.path.suffix or '(no s
- directory looks like a full diffusers pipeline (has model_in
- missing text_encoder/ subfolder
- Unexpected key: {k}
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/170030a0524571f8.
Report an issue: GitHub.