LykosAI/StabilityMatrix · error · FileNotFoundException

Expected SageAttention file

Error message

Expected SageAttention file '{fileName}' was not found.

What it means

DownloadAndReplaceFileAsync expects the SageAttention wheel/source file (given by fileName) to already exist inside the package's SageAttention directory (sageAttentionDir). It joins the directory and file name, and if the file is absent throws FileNotFoundException including the full path. This happens after a download/extraction step should have placed the file, so its absence means an earlier step produced nothing at the expected path.

Solutions

  1. Delete the package's SageAttention directory and rerun the Windows ROCm install step so the download runs fresh.
  2. Compare the fileName in the exception to the actual files in the SageAttention directory; if upstream renamed assets, update the step's expected file name / download URL to the new asset name.
  3. Verify the prior download step's logs for a failed or empty download (network/proxy issues) and retry on a working connection.
  4. Manually download the expected SageAttention artifact from the upstream release and place it at the path in the exception message, then rerun.
  5. Ensure the torch/CUDA-or-ROCm variant expected by the step actually has a published wheel; pick a package/torch version combination that does.
Defensive patterns

Strategy: validation

Validate before calling

var targetFile = sageAttentionDir.JoinFile(fileName);
if (!targetFile.Exists)
{
    logger.LogWarning("SageAttention artifact missing: {Path}", targetFile.FullPath);
    // re-run the download step or correct fileName before calling DownloadAndReplaceFileAsync
    return;
}

Try / catch

try
{
    await ExecuteSageAttentionAsync(dir, progress, ct);
}
catch (FileNotFoundException ex)
{
    logger.LogError(ex, "SageAttention file missing: {File}", ex.FileName);
    // remediate: wipe sageAttentionDir, re-download from upstream release, then retry once
}

Prevention

When it happens

Trigger: ExecuteSageAttentionAsync calls DownloadAndReplaceFileAsync for an expected SageAttention artifact (e.g. a .whl or patch file) whose name was computed for the package, but the file is not present under sageAttentionDir when the existence check runs — typically because the upstream GitHub release asset was renamed, the download silently failed, or extraction put it in a different subfolder.

Common situations: Upstream SageAttention release changed asset file names so the hardcoded/computed fileName no longer matches; a proxy/firewall or GitHub outage left a zero-byte or missing file after the previous step; a cached/partial install from a failed prior run skipped the download step; the ROCm-specific wheel variant (e.g. torch 2.x + cu/rocm tags) does not exist so nothing matching was placed in the directory.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at StabilityMatrix.Core/Models/PackageModification/InstallWindowsRocmPackageCommandStep.cs:256

        await venvRunner.PipInstall(AmdAiterWheelUrl).ConfigureAwait(false);

        progress?.Report(
            new ProgressReport(-1f, "Installing Flash Attention for Windows ROCm...", isIndeterminate: true)
        );
        await venvRunner.PipInstall(FlashAttentionWheelUrl).ConfigureAwait(false);
    }

    private async Task DownloadAndReplaceFileAsync(
        DirectoryPath sageAttentionDir,
        string fileName,
        string sourceUrl,
        IProgress<ProgressReport>? progress
    )
    {
        var targetFile = sageAttentionDir.JoinFile(fileName);
        if (!targetFile.Exists)
        {
            throw new FileNotFoundException(
                $"Expected SageAttention file '{fileName}' was not found.",
                targetFile.FullPath
            );
        }

        var backupFile = sageAttentionDir.JoinFile($"{fileName}.bak");
        if (!backupFile.Exists)
        {
            await backupFile
                .WriteAllTextAsync(await targetFile.ReadAllTextAsync().ConfigureAwait(false))
                .ConfigureAwait(false);
        }

        var tempFile = WorkingDirectory.JoinFile($"sm-rocm-sage-{fileName}.tmp");
        await downloadService.DownloadToFileAsync(sourceUrl, tempFile, progress).ConfigureAwait(false);

        try
        {

View on GitHub (pinned to af93d6ef57)