{"record":{"id":"52471c164db20132","repo":"can1357/oh-my-pi","slug":"speech-model-download-finished-without-required-fi","errorCode":null,"errorMessage":"Speech model download finished without required files (${spec.repo}).","messagePattern":"Speech model download finished without required files \\((.+?)\\)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/stt/downloader.ts","lineNumber":124,"sourceCode":"\t\t\tconst settled = event.status === \"ready\" || event.status === \"done\";\n\t\t\tconst percent = total > 0 ? Math.min(100, Math.round((loaded / total) * 100)) : settled ? 100 : 0;\n\t\t\tonProgress?.({\n\t\t\t\tstatus: event.status,\n\t\t\t\tpercent,\n\t\t\t\tloaded,\n\t\t\t\ttotal,\n\t\t\t\tfile: event.file,\n\t\t\t\trepo: spec.repo,\n\t\t\t\tlabel: spec.label,\n\t\t\t});\n\t\t},\n\t});\n\tif (!result.ok) {\n\t\tconst detail = result.error ? `: ${result.error}` : \". Check your network connection.\";\n\t\tthrow new Error(`Failed to download speech model (${spec.repo})${detail}`);\n\t}\n\tif (!(await isSttModelCached(spec.key))) {\n\t\tthrow new Error(`Speech model download finished without required files (${spec.repo}).`);\n\t}\n}\n\n// ── Public API ─────────────────────────────────────────────────────\n\nexport async function ensureSTTDependencies(options?: EnsureOptions): Promise<void> {\n\tawait downloadSttModel(\n\t\tresolveSttModelSpec(options?.modelName).key,\n\t\tprogress => {\n\t\t\tconst stage =\n\t\t\t\tprogress.status === \"ready\" || progress.status === \"done\"\n\t\t\t\t\t? `Speech model ${progress.label} ready`\n\t\t\t\t\t: `Downloading speech model ${progress.label}`;\n\t\t\toptions?.onProgress?.({ stage, percent: progress.percent });\n\t\t},\n\t\t{ signal: options?.signal },\n\t);\n}","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/stt/downloader.ts#L106-L142","documentation":"After the worker reports a successful download, downloadSttModel double-checks on disk with isSttModelCached that every required file is actually present (config.json plus encoder/decoder ONNX shards for Whisper tiers; encoder/decoder/joiner/tokens for sherpa tiers; .part sidecars ignored). If verification fails, the download claimed success but left an incomplete cache, and this error is thrown.","triggerScenarios":"The worker reports done/ready but the cache directory lacks required files — an interrupted write that was misreported, files written to a different cache dir than getTinyModelsCacheDir() reads, or something deleted files between download and verification.","commonSituations":"Concurrent runs racing on the same cache directory, a redirected/moved cache dir (XDG/env change) so verification looks in the wrong place, antivirus or cleanup tools removing large ONNX files, or a buggy/short-circuited worker completion event.","solutions":["Delete the model's cache directory under the tiny-models cache and re-download.","Confirm the cache directory (getTinyModelsCacheDir) is stable between runs — check XDG/HOME env overrides.","Exclude the cache directory from antivirus/cleanup tooling.","Retry the download; if reproducible, compare the on-disk file list with the spec's required files."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import { isSttModelCached } from \"./downloader\";\nif (!(await isSttModelCached(key))) await downloadSttModel(key); // verify-or-redownload","typeGuard":null,"tryCatchPattern":"try { await downloadSttModel(key); } catch (err) { if (String(err).includes(\"without required files\")) { await rm(repoDir, { recursive: true, force: true }); await downloadSttModel(key); } else throw err; }","preventionTips":["Always gate on isSttModelCached instead of trusting a done event.","Keep the cache directory stable — avoid runtime changes to XDG/HOME env that relocate it.","Exclude the model cache from antivirus/cleanup tools that delete large ONNX files.","Avoid concurrent processes racing on the same cache directory."],"tags":["cache","verification","stt","download"],"backgroundTag":"incomplete-model-cache","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}