{"record":{"id":"4a85d35794c9cea8","repo":"SubtitleEdit/subtitleedit","slug":"zonos-tts-crispasr-model-filename-failed-integ","errorCode":null,"errorMessage":"Zonos TTS (CrispASR) model {fileName} failed integrity check (expected SHA-256 {expected}, got {actual}).","messagePattern":"Zonos TTS \\(CrispASR\\) model (.+?) failed integrity check \\(expected SHA-256 (.+?), got (.+?)\\)\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"src/ui/Logic/Download/ZonosTtsCrispAsrDownloadService.cs","lineNumber":130,"sourceCode":"        {\n            return;\n        }\n\n        var expected = DownloadHashManager.GetLatestKnownHash(key);\n        if (string.IsNullOrEmpty(expected))\n        {\n            return;\n        }\n\n        string actual;\n        await using (var stream = File.OpenRead(filePath))\n        {\n            actual = await Sha256Util.ComputeSha256Async(stream, cancellationToken);\n        }\n\n        if (!string.Equals(expected, actual, StringComparison.OrdinalIgnoreCase))\n        {\n            throw new IOException(\n                $\"Zonos TTS (CrispASR) model {fileName} failed integrity check (expected SHA-256 {expected}, got {actual}).\");\n        }\n    }\n\n    private static string GetUrl(string fileName)\n    {\n        if (!ModelUrls.TryGetValue(fileName, out var url))\n        {\n            throw new ArgumentException($\"Unknown Zonos TTS (CrispASR) model: {fileName}\", nameof(fileName));\n        }\n        return url;\n    }\n\n    private static void TryDelete(string path)\n    {\n        try { File.Delete(path); } catch { /* best-effort cleanup */ }\n    }\n","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/ui/Logic/Download/ZonosTtsCrispAsrDownloadService.cs#L112-L148","documentation":"Thrown by ZonosTtsCrispAsrDownloadService.VerifyFile when the SHA-256 of a freshly downloaded Zonos TTS model (the q8_0 transformer or the DAC codec) does not match the pinned expected hash from DownloadHashManager. Unlike yt-dlp (error 369, which auto-deletes), here the .part file cleanup happens in the DownloadAndVerify catch, and the exception type is IOException. The mismatch signals truncation, corruption, or a mirror that served different bytes.","triggerScenarios":"After DownloadHelper downloads the talker or codec .gguf to a .part file, ComputeSha256Async diverges from DownloadHashManager.GetLatestKnownHash(key). Causes: truncated download, MITM/proxy, partial write, or an updated model whose hash was not yet pinned.","commonSituations":"Hugging Face mirror serving a re-quantized file; a large (~1.8GB) talker model truncated by a dropped connection; the pinned hash in DownloadHashManager out of date after an upstream re-release.","solutions":["Retry the download once — the .part file is deleted on failure so the next attempt is clean.","If it persists, download the .gguf manually from the Hugging Face URL in ModelUrls and verify its SHA-256 against the published value, then place it at the expected path.","Confirm the pinned hash in DownloadHashManager.ZonosTtsCrispAsr matches the current upstream release.","Check for a corporate proxy altering file bytes."],"exampleFix":"// before\nawait _zonos.DownloadModels(folder, progress, titleProgress, ct);\n\n// after: one retry on integrity failure\ntry { await _zonos.DownloadModels(folder, progress, titleProgress, ct); }\ncatch (IOException ex) when (ex.Message.Contains(\"failed integrity check\"))\n{\n    await _zonos.DownloadModels(folder, progress, titleProgress, ct);\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await svc.DownloadModels(folder, progress, titleProgress, ct); }\ncatch (IOException ex) when (ex.Message.Contains(\"failed integrity check\"))\n{ await svc.DownloadModels(folder, progress, titleProgress, ct); } // .part was cleaned; one retry","preventionTips":["Keep the pinned hashes in DownloadHashManager.ZonosTtsCrispAsr aligned with upstream Hugging Face releases.","Avoid proxies that rewrite large .gguf downloads."],"tags":["zonos","tts","model","download","sha256","integrity","checksum"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}