{"record":{"id":"d4a894ee990b386d","repo":"SubtitleEdit/subtitleedit","slug":"kokoro-tts-model-or-voices-file-missing","errorCode":null,"errorMessage":"Kokoro TTS model or voices file missing.","messagePattern":"Kokoro TTS model or voices file missing\\.","errorType":"exception","errorClass":"FileNotFoundException","httpStatus":null,"severity":"error","filePath":"src/ui/Features/Video/TextToSpeech/Engines/KokoroTtsCpp.cs","lineNumber":305,"sourceCode":"        try\n        {\n            if (_serverProcess is { HasExited: false } && _serverPort != 0)\n            {\n                return;\n            }\n\n            var exe = GetExecutableFileName();\n            if (!File.Exists(exe))\n            {\n                throw new FileNotFoundException(\"Kokoro TTS server executable not found.\", exe);\n            }\n\n            var modelsFolder = GetSetModelsFolder();\n            var modelPath  = Path.Combine(modelsFolder, TtsModelFileName);\n            var voicesPath = Path.Combine(modelsFolder, VoicesModelFileName);\n            if (!File.Exists(modelPath) || !File.Exists(voicesPath))\n            {\n                throw new FileNotFoundException(\"Kokoro TTS model or voices file missing.\",\n                    File.Exists(modelPath) ? voicesPath : modelPath);\n            }\n\n            var port = FindFreeLoopbackPort();\n            var psi = new ProcessStartInfo\n            {\n                // Working directory must be GetSetFolder() so the server can find dict/vocab.txt\n                // (relative path baked into the binary's default --vocab arg).\n                WorkingDirectory = GetSetFolder(),\n                FileName = exe,\n                UseShellExecute = false,\n                CreateNoWindow = true,\n                RedirectStandardError = true,\n                RedirectStandardOutput = true,\n            };\n            psi.ArgumentList.Add(\"-m\");\n            psi.ArgumentList.Add(modelPath);\n            psi.ArgumentList.Add(\"-V\");","sourceCodeStart":287,"sourceCodeEnd":323,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/ui/Features/Video/TextToSpeech/Engines/KokoroTtsCpp.cs#L287-L323","documentation":"FileNotFoundException from KokoroTtsCpp.EnsureServerRunningAsync when either the model file (TtsModelFileName) or the voices file (VoicesModelFileName) is absent in GetSetModelsFolder(). The exception's FileName is set to whichever of the two is missing (voices if the model exists, else model). The server binary is present but cannot run without its model assets.","triggerScenarios":"Model/voices download was interrupted leaving one file present and one missing; the models folder was partially cleared; a version upgrade renamed the expected model file but only one was re-downloaded; the folder was moved and assets left behind.","commonSituations":"Partial download after a network drop; user deleted the large model file but kept the small voices file; settings point GetSetModelsFolder() at a folder that lacks the assets.","solutions":["Re-download the Kokoro model and voices files into GetSetModelsFolder().","Confirm both TtsModelFileName and VoicesModelFileName exist and are non-zero bytes.","Point the models folder setting at the location that actually contains both files.","If only one file is missing, download just that one — the FileName field tells you which."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"var folder = engine.GetSetModelsFolder();\nif (!File.Exists(Path.Combine(folder, TtsModelFileName)) ||\n    !File.Exists(Path.Combine(folder, VoicesModelFileName)))\n{\n    PromptDownloadKokoroModels();\n    return;\n}","typeGuard":null,"tryCatchPattern":"try { await kokoroEngine.Speak(...); }\ncatch (FileNotFoundException ex) when (ex.Message.Contains(\"model or voices file missing\"))\n{\n    PromptDownloadKokoroModels(ex.FileName); // FileName tells which one\n}","preventionTips":["Download both model and voices files atomically; verify sizes after.","Re-verify both files after any folder/settings change.","Disable the engine until both assets are present.","Re-download if a file is zero bytes (interrupted transfer)."],"tags":["kokoro","file-not-found","model-files","tts"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}