{"record":{"id":"402d426e8170f18a","repo":"LykosAI/StabilityMatrix","slug":"python-version-download-hash-mismatch-expected-hashsha256","errorCode":null,"errorMessage":"Python {version} download hash mismatch: expected {hashSha256}, actual {actualHash}","messagePattern":"Python (.+?) download hash mismatch: expected (.+?), actual (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"StabilityMatrix.Avalonia/Helpers/UnixPrerequisiteHelper.cs","lineNumber":342,"sourceCode":"\n        // Download\n        var remote = GetPythonDownloadResource(version);\n        var url = remote.Url;\n        var hashSha256 = remote.HashSha256;\n\n        var fileName = Path.GetFileName(url.LocalPath);\n        var downloadPath = Path.Combine(AssetsDir, fileName);\n        Logger.Info($\"Downloading Python {version} from {url} to {downloadPath}\");\n        try\n        {\n            await downloadService.DownloadToFileAsync(url.ToString(), downloadPath, progress);\n\n            // Verify hash\n            var actualHash = await FileHash.GetSha256Async(downloadPath);\n            Logger.Info($\"Verifying Python {version} hash: (expected: {hashSha256}, actual: {actualHash})\");\n            if (actualHash != hashSha256)\n            {\n                throw new Exception(\n                    $\"Python {version} download hash mismatch: expected {hashSha256}, actual {actualHash}\"\n                );\n            }\n\n            // Extract\n            Logger.Info($\"Extracting Python {version} Zip: {downloadPath} to {pythonDir}\");\n            if (pythonDir.Exists)\n            {\n                await pythonDir.DeleteAsync(true);\n            }\n            progress?.Report(new ProgressReport(0, $\"Installing Python {version}\", isIndeterminate: true));\n            await ArchiveHelper.Extract7ZAuto(downloadPath, pythonDir);\n\n            // For Unix, move the inner 'python' folder up to the root PythonDir\n            if (Compat.IsUnix)\n            {\n                var innerPythonDir = pythonDir.JoinDir(\"python\");\n                if (!innerPythonDir.Exists)","sourceCodeStart":324,"sourceCodeEnd":360,"githubUrl":"https://github.com/LykosAI/StabilityMatrix/blob/af93d6ef57c01cd890d7e0ad0a9ea8c9fcda3002/StabilityMatrix.Avalonia/Helpers/UnixPrerequisiteHelper.cs#L324-L360","documentation":"InstallPythonIfNecessary downloads a Python tarball for Unix and verifies its SHA-256 against an expected hash; a mismatch (corrupted, truncated, or replaced download) throws a plain Exception with expected vs actual hashes. This prevents extracting a tampered or incomplete Python distribution.","triggerScenarios":"SHA-256 of the downloaded python-{version}-amd64.tar.gz differs from hashSha256 — download interrupted mid-stream, server/proxy returning an error page instead of the archive, or a mirrored file changed upstream.","commonSituations":"Flaky network or captive portal truncating large downloads; corporate proxy substituting content; CDN serving stale/partial file; disk full silently corrupting the written file.","solutions":["Delete the bad tar.gz from the Assets directory and retry the Python install on a stable connection.","Check for proxy/VPN/firewall interference that could alter or truncate the download.","Free disk space and ensure the app has write access to the assets path.","If the upstream hash changed, update Stability Matrix (the expected hash ships with the app)."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"var expected = ExpectedHashes[version];\nvar actual = await FileHash.GetSha256Async(downloadPath);\nif (actual != expected) File.Delete(downloadPath); // force re-download","typeGuard":null,"tryCatchPattern":"try { await helper.InstallPythonIfNecessary(version); }\ncatch (Exception ex) when (ex.Message.Contains(\"hash mismatch\"))\n{ logger.Warn(\"Python download corrupted; deleting and retrying...\"); File.Delete(downloadPath); await RetryWithBackoff(); }","preventionTips":["Use a stable wired connection for large downloads.","Exclude the app's download path from proxy/AV interception.","Ensure sufficient free disk space before downloading.","Update Stability Matrix when upstream hashes change."],"tags":["python","sha256","download","integrity","unix"],"backgroundTag":"checksum-mismatch","analyzedSha":"af93d6ef57c01cd890d7e0ad0a9ea8c9fcda3002","analyzedAt":"2026-09-12T19:02:43.389Z","contentChangedAt":"2026-09-12T19:02:43.389Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}