invoke-ai/InvokeAI · error · HTTPException
The model with key {key} is not a main SD 1/2/XL checkpoint
Error message
The model with key {key} is not a main SD 1/2/XL checkpoint model. What it means
HTTP 400 raised by POST /models/convert/{key} when the model record for the given key is not one of the main SD1/SD2/SDXL/SDXL-Refiner checkpoint configs. The converter only knows how to transform a single-file checkpoint model into a diffusers folder; other model types (LoRAs, VAEs, ControlNets, diffusers-format mains) have nothing to convert. The isinstance check against the four config classes is the guard.
Source
Thrown at invokeai/app/api/routers/model_manager.py:1296
try:
model_config = store.get_model(key)
except UnknownModelException as e:
logger.error(str(e))
raise HTTPException(status_code=424, detail=str(e))
if not isinstance(
model_config,
(
Main_Checkpoint_SD1_Config,
Main_Checkpoint_SD2_Config,
Main_Checkpoint_SDXL_Config,
Main_Checkpoint_SDXLRefiner_Config,
),
):
msg = f"The model with key {key} is not a main SD 1/2/XL checkpoint model."
logger.error(msg)
raise HTTPException(400, msg)
# Under the models root so `install_path` below moves the result rather than copying it across
# a filesystem boundary, but inside the scratch directory the orphan scan skips: a half-written
# diffusers copy is model files with no database record, which is exactly what that scan hunts
# for, and `DELETE /sync/orphaned` would rmtree it while it is still being written.
scratch_dir = ApiDependencies.invoker.services.configuration.models_path / CONVERSION_SCRATCH_DIRNAME
scratch_dir.mkdir(parents=True, exist_ok=True)
with TemporaryDirectory(dir=scratch_dir) as tmpdir:
convert_path = pathlib.Path(tmpdir) / pathlib.Path(model_config.path).stem
converted_model = loader.load_model(model_config, user_id=user_id)
# write the converted file to the convert path
raw_model = converted_model.model
assert hasattr(raw_model, "save_pretrained")
raw_model.save_pretrained(convert_path) # type: ignore
assert convert_path.exists()
# temporarily rename the original safetensors file so that there is no naming conflictView on GitHub (pinned to 0b6a024f2f)
Solutions
- Verify the model key refers to a main checkpoint model (SD1/SD2/SDXL/Refiner) in the model manager
- Call GET /api/v1/models/i/{key} and confirm its type/base are main checkpoint, not LoRA/VAE/ControlNet/diffusers-main
- If the model is already diffusers format, no conversion is needed — use it directly
- If you intended to convert a different model, fetch the correct key from the model list
Example fix
// before: blind conversion of any key
await api.convertModel(key);
// after: check type first
const cfg = await api.getModelConfig(key);
if (cfg.type === 'main' && cfg.format === 'checkpoint') await api.convertModel(key);
else throw new Error(`Model ${key} is not convertible`); Defensive patterns
Strategy: validation
Validate before calling
const cfg = await api.getModelConfig(key);
if (!(cfg.type === 'main' && cfg.format === 'checkpoint')) {
throw new Error(`Model ${key} (${cfg.type}/${cfg.format}) cannot be converted`);
} Type guard
function isConvertibleMainCheckpoint(cfg) {
return cfg != null && cfg.type === 'main' && cfg.format === 'checkpoint';
} Try / catch
try {
await api.convertModel(key);
} catch (e) {
if (e.status === 400 && /not a main SD/.test(e.body?.detail ?? '')) {
console.warn(`Skip ${key}: not a checkpoint model`);
} else throw e;
} Prevention
- Check the model's type/format via the model config endpoint before converting
- Never iterate all model keys blindly converting each one
- Remember diffusers-format main models do not need conversion
- Label checkpoint vs diffusers models in any custom UI
When it happens
Trigger: Calling convert_model (POST /api/v1/models/convert/{key}) with the key of a model whose stored config class is not Main_Checkpoint_SD1_Config / SD2 / SDXL / SDXLRefiner — e.g. converting a diffusers-format main model, a LoRA, VAE, ControlNet, or T2I adapter.
Common situations: Users selecting the wrong model in the UI conversion dialog; scripts iterating all model keys and converting each; trying to 'convert' an already-converted diffusers model; confusing a LoRA key with a main model key.
Related errors
- No external provider config fields provided
- Administrator account already configured
- str(e)
- The system user cannot be deleted, deactivated, promoted to
- Cannot remove the last administrator
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/c4bac1c4b6027069.
Report an issue: GitHub.