LykosAI/StabilityMatrix · error · InvalidOperationException

Flux.2 Klein UNET model not found

Error message

Flux.2 Klein UNET model not found

What it means

Flux2KleinModelManager.SelectModels must locate a locally installed Flux.2 Klein UNET among the ComfyUI client's known models. If no model with a Local file matching IsKleinUnet exists (and no preferredUnet was supplied), it throws this InvalidOperationException because a Klein workflow cannot be built without the UNET.

Solutions

  1. Download a Flux.2 Klein UNET safetensors into the ComfyUI models folder and refresh the model index
  2. Pass an explicit preferredUnet (HybridModelFile with Local set) to SelectModels
  3. Catch InvalidOperationException and prompt the user to install the missing UNET before launching the workflow

Example fix

// before
var models = flux2KleinModelManager.SelectModels();
// after
if (!clientManager.UnetModels.Any(m => m.Local != null && IsKleinUnet(m.FileName)))
{
    throw new UserDownloadableError("Flux.2 Klein UNET is not installed. Download it before running this workflow.");
}
var models = flux2KleinModelManager.SelectModels();
Defensive patterns

Strategy: validation

Validate before calling

var unet = clientManager.UnetModels.FirstOrDefault(m => m.Local != null && IsKleinUnet(m.FileName));
if (unet is null) throw new UserDownloadableError("Flux.2 Klein UNET is not installed; download it before running.");

Type guard

bool HasLocalKleinUnet(IEnumerable<HybridModelFile> models) => models.Any(m => m.Local != null && IsKleinUnet(m.FileName));

Try / catch

try
{
    var models = flux2KleinModelManager.SelectModels();
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Klein UNET model not found"))
{
    // trigger UNET download flow
}

Prevention

When it happens

Trigger: Calling SelectModels (directly or via selectedModels) with no preferredUnet while clientManager.UnetModels contains no entry with Local != null whose FileName matches IsKleinUnet — i.e. the Klein UNET checkpoint was never downloaded or is registered without a local file.

Common situations: User selects the Flux.2 Klein workflow before downloading the UNET; model downloaded into the wrong folder so it isn't indexed as local; stale ComfyUI model index where the remote entry exists but Local is null.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of LykosAI/StabilityMatrix@af93d6ef57 (2026-09-12). Data as JSON: /api/errors/ba8deff6714ebb7d. Report an issue: GitHub.

Appendix: source

Thrown at StabilityMatrix.Avalonia/Services/Flux2KleinModelManager.cs:164

            ?? clientManager.UnetModels.FirstOrDefault(m => m.Local != null && IsKleinUnet(m.FileName));

        return unet != null ? GetExpectedEncoderSize(unet) : "4b";
    }

    /// <summary>
    /// Select the best available models for Flux.2 Klein (only LOCAL models).
    /// When the selected UNET is the 9B variant, prefers the matching qwen_3_8b text encoder;
    /// when 4B, prefers qwen_3_4b. Falls back to whichever encoder is present.
    /// </summary>
    internal SelectedModels SelectModels(
        IInferenceClientManager clientManager,
        HybridModelFile? preferredUnet = null
    )
    {
        var unetModel =
            preferredUnet
            ?? clientManager.UnetModels.FirstOrDefault(m => m.Local != null && IsKleinUnet(m.FileName))
            ?? throw new InvalidOperationException("Flux.2 Klein UNET model not found");

        var vaeModel =
            clientManager.VaeModels.FirstOrDefault(m => m.Local != null && IsFlux2Vae(m.FileName))
            ?? throw new InvalidOperationException("Flux.2 VAE model not found");

        // Match the text encoder to the selected UNET variant. The 4B UNET expects
        // qwen_3_4b (~4B params, hidden_dim 2560) and the 9B UNET expects qwen_3_8b
        // (~8B params, hidden_dim 4096) — pairing the wrong size produces a tensor
        // shape mismatch deep inside the sampler, so we fail fast here with a clear
        // message rather than silently substituting the other size.
        var preferredEncoderSize = GetExpectedEncoderSize(unetModel);

        var clipModel =
            clientManager.ClipModels.FirstOrDefault(m =>
                m.Local != null
                && IsKleinTextEncoder(m.FileName)
                && MatchesEncoderSize(m.FileName, preferredEncoderSize)
            )

View on GitHub (pinned to af93d6ef57)