mihomo-party-org/clash-party · error · Error

Failed to fetch version list

Error message

Failed to fetch version list

What it means

The fallback branch of getGitHubTags: when the caught value is NOT an Error instance (e.g. a string was thrown, or an odd rejection shape from an underlying fetch layer), it throws the generic message 'Failed to fetch version list'. It carries less information than error 82 by design, since the original throwable's message could not be safely extracted.

Source

Thrown at src/main/utils/github.ts:117

        responseType: 'json',
        timeout: 10000
      }
    )

    // 更新缓存
    versionCache.set(cacheKey, {
      data: response.data,
      timestamp: Date.now()
    })

    log.debug(`Successfully fetched ${response.data.length} tags for ${owner}/${repo}`)
    return response.data
  } catch (error) {
    log.error(`Failed to fetch tags for ${owner}/${repo}`, error)
    if (error instanceof Error) {
      throw new Error(`GitHub API error: ${error.message}`)
    }
    throw new Error('Failed to fetch version list')
  }
}

/**
 * 清除版本缓存
 * @param owner 仓库所有者
 * @param repo 仓库名称
 */
export function clearVersionCache(owner: string, repo: string): void {
  const cacheKey = `${owner}/${repo}`
  const hasCache = versionCache.has(cacheKey)
  versionCache.delete(cacheKey)
  log.debug(`Cache ${hasCache ? 'cleared' : 'not found'} for ${owner}/${repo}`)
}

/**
 * 下载 GitHub Release 资产
 * @param url 下载 URL

View on GitHub (pinned to 911e090537)

Solutions

  1. Check the app log line 'Failed to fetch tags for owner/repo' which contains the original raw value for the real cause.
  2. Test connectivity to api.github.com directly; treat as a network/API availability problem first.
  3. If a custom transport/interceptor is in play, make it reject with Error instances instead of strings.
  4. Add a retry with backoff, since the cause is usually transient network failure.

Example fix

// before: transport rejecting with a string
reject('timeout')
// after
reject(new Error(`timeout`))
Defensive patterns

Strategy: fallback

Validate before calling

// preflight connectivity check
const online = await fetch('https://api.github.com', { method: 'HEAD' }).then((r) => r.ok).catch(() => false)
if (!online) throw new Error('api.github.com unreachable')

Try / catch

let tags: Tag[]
try {
  tags = await getGitHubTags(owner, repo)
} catch (e) {
  log.warn('Version check failed, using cached list', e)
  tags = cachedTags ?? []
}

Prevention

When it happens

Trigger: fetchMihomoTags -> getGitHubTags where the underlying request layer rejects with a non-Error value — e.g. a thrown string, an undefined rejection, or a proxy library rejecting with a plain object.

Common situations: Custom request adapters/interceptors that reject with strings; patched or mocked HTTP layers in odd environments; older versions of the transport rejecting without Error objects.

Related errors


AI-assisted analysis of mihomo-party-org/clash-party@911e090537 (2026-08-30). Data as JSON: /api/errors/b4c609f534a908a0. Report an issue: GitHub.