LykosAI/StabilityMatrix · error · InvalidOperationException

Unable to get preview image file extension from from Uri…

Error message

Unable to get preview image file extension from from Uri, and no file extension provided

What it means

DoCustomImport throws this InvalidOperationException when it needs to download a preview image but cannot determine the file extension: the URI's local path has no extension and the caller did not supply previewImageFileExtension. The service requires an extension to build the destination file path.

Solutions

  1. Pass previewImageFileExtension explicitly (e.g. ".jpeg") when the preview URL lacks one
  2. Inspect the HTTP Content-Type header of the preview URL and derive the extension from it
  3. Use a preview URL that includes a real file extension if you control the source
  4. Default to the known image type (e.g. .jpg for Civitai image endpoints) when constructing the import call

Example fix

// before
await importService.DoCustomImport(downloadUri, "model.safetensors", localModelFile, modelDbModel, previewImageUri: blobUri);
// after
await importService.DoCustomImport(downloadUri, "model.safetensors", localModelFile, modelDbModel,
    previewImageUri: blobUri,
    previewImageFileExtension: ".jpeg"); // explicit, since blobUri has no extension
Defensive patterns

Strategy: try-catch

Validate before calling

var ext = previewImageFileExtension ?? Path.GetExtension(previewImageUri.LocalPath);
if (string.IsNullOrEmpty(ext))
    ext = ".jpeg"; // or derive from Content-Type via a HEAD request

Type guard

bool HasPreviewExtension(Uri uri) => !string.IsNullOrEmpty(Path.GetExtension(uri.LocalPath));

Try / catch

try
{
    await importService.DoCustomImport(...);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("preview image file extension"))
{
    // retry with an explicit previewImageFileExtension
}

Prevention

When it happens

Trigger: Importing a model whose preview image URL has no extension (e.g. signed/blob URLs like ...?token=x or /preview/12345) without passing previewImageFileExtension.

Common situations: Civitai or CDN preview URLs behind redirects that hide extensions; blob-storage URLs with query parameters only; custom preview image links without a file suffix; programmatic imports omitting the optional extension parameter.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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

Appendix: source

Thrown at StabilityMatrix.Avalonia/Services/ModelImportService.cs:334

        // fetching the preview in the background.
        var cleanupFilePaths = new List<string>();
        if (connectedModelInfo is not null)
        {
            await connectedModelInfo.SaveJsonToDirectory(downloadFolder, modelBaseFileName);
            cleanupFilePaths.Add(
                downloadFolder.JoinFile(modelBaseFileName + ConnectedModelInfo.FileExtension)
            );
        }

        FilePath? previewImageDownloadPath = null;
        if (previewImageUri is not null)
        {
            if (previewImageFileExtension is null)
            {
                previewImageFileExtension = Path.GetExtension(previewImageUri.LocalPath);
                if (string.IsNullOrEmpty(previewImageFileExtension))
                {
                    throw new InvalidOperationException(
                        "Unable to get preview image file extension from from Uri, and no file extension provided"
                    );
                }
            }

            previewImageDownloadPath = downloadFolder.JoinFile(
                modelBaseFileName + ".preview" + previewImageFileExtension
            );

            cleanupFilePaths.Add(previewImageDownloadPath);
        }

        // Create tracked download
        // todo: support multiple uris
        var modelUri = modelUris.First();
        var download = trackedDownloadService.NewDownload(modelUri, downloadPath);

        // Add hash info

View on GitHub (pinned to af93d6ef57)