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 conflict

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Verify the model key refers to a main checkpoint model (SD1/SD2/SDXL/Refiner) in the model manager
  2. Call GET /api/v1/models/i/{key} and confirm its type/base are main checkpoint, not LoRA/VAE/ControlNet/diffusers-main
  3. If the model is already diffusers format, no conversion is needed — use it directly
  4. 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

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


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/c4bac1c4b6027069. Report an issue: GitHub.