mihomo-party-org/clash-party · error · Error
Executable file not found in zip: ${exeFile}
Error message
Executable file not found in zip: ${exeFile} What it means
After downloading the Windows .zip distribution of mihomo, installMihomoCore opens it with an unzip library, searches entries for one whose name includes exeFile, and throws 'Executable file not found in zip: <exeFile>' when no entry matches. It means the archive layout changed upstream or the downloaded file is not the expected zip.
Source
Thrown at src/main/utils/github.ts:218
// 先停止核心
await stopCore(true)
}
// 下载文件
await downloadGitHubAsset(downloadURL, tempZip)
// 解压文件
if (urlExt === 'zip') {
log.debug(`Extracting ZIP file ${tempZip}`)
const zip = new AdmZip(tempZip)
const entries = zip.getEntries()
const entry = entries.find((e) => e.entryName.includes(exeFile))
if (entry) {
zip.extractEntryTo(entry, coreDir, false, true, false, targetFile)
log.debug(`Successfully extracted ${exeFile} to ${targetPath}`)
} else {
throw new Error(`Executable file not found in zip: ${exeFile}`)
}
} else {
// 处理.gz 文件
// 先解压到临时文件再原子替换:直接往 targetPath 写的话,解压中途失败
// 会把原本可用的内核截断成半个文件,用户连回退都没得回退。
log.debug(`Extracting GZ file ${tempZip}`)
const stagingPath = `${targetPath}.download`
const readStream = createReadStream(tempZip)
const writeStream = createWriteStream(stagingPath)
try {
await new Promise<void>((resolve, reject) => {
const gunzip = createGunzip()
const onError = (error: Error): void => {
log.error('Gzip decompression failed', error)
readStream.destroy()
gunzip.destroy()
writeStream.destroy()View on GitHub (pinned to 911e090537)
Solutions
- Re-download from official GitHub (bypass mirrors) to rule out an error page or truncated zip.
- Open the downloaded zip and confirm the actual executable name; update the expected exeFile string/PLATFORM_MAP filename to match the release layout.
- Switch to a mihomo version whose zip layout matches the expected entry name (renames happen between versions).
- Verify zip size against the release asset size before extraction to catch truncated downloads.
Example fix
// before: brittle exact expectation const exeFile = 'mihomo.exe' // after: tolerate upstream naming changes const entry = entries.find( (e) => e.entryName.includes(exeFile) || /mihomo.*windows.*\.(exe)$/i.test(e.entryName) )
Defensive patterns
Strategy: validation
Validate before calling
import AdmZip from 'adm-zip'
// inspect the archive before extraction to confirm the executable entry exists
const zip = new AdmZip(tempZip)
const hasExe = zip.getEntries().some((e) => e.entryName.endsWith('.exe'))
if (!hasExe) {
throw new Error('Downloaded zip contains no .exe; likely an error page or wrong asset')
} Try / catch
try {
await installSpecificMihomoCore(version)
} catch (e) {
if (String(e).includes('Executable file not found in zip')) {
// re-download from official source, or loosen the entry matcher for renamed binaries
await reinstallFromOfficialSource(version)
} else {
throw e
}
} Prevention
- Verify downloaded archive size against the release asset size before extraction
- Match zip entries by regex (e.g. /mihomo.*windows.*\.exe$/) instead of a fixed filename
- Download from official GitHub to avoid HTML error pages saved as .zip
- Test installs against new mihomo versions whenever the upstream renames artifacts
When it happens
Trigger: installMihomoCore with isWin=true where the extracted zip has no entry containing the expected exe name — mihomo renamed the executable between versions, the zip nests it under a different directory prefix than expected, or the 'zip' is actually an HTML error page saved as .zip (a 200-response mirror).
Common situations: Pinning an old/new mihomo version whose binary is named mihomo-windows-amd64-v*.exe vs mihomo.exe; a mirror serving a captcha/error page with 200 status; partial/corrupt download producing a valid-but-empty zip.
Related errors
- Failed to install core: ${error instanceof Error ? error.mes
- Unsupported platform "${plat}-${arch}"
- HTTP ${response.status} ${response.statusText}
- Failed to parse process list JSON:
AI-assisted analysis of mihomo-party-org/clash-party@911e090537 (2026-08-30).
Data as JSON: /api/errors/5e246edaa152ddb0.
Report an issue: GitHub.