#112615·hermes-agent

Desktop update check fails behind a shared exit IP (anonymous GitHub API, 60/hour per IP)

Author: DaxLee9988Created Sep 16, 2026Updated Sep 17, 2026
Labelstype/bugduplicateP2comp/desktoparea/install-update

Symptom

The desktop app's update panel reports, under the generic "can't reach the update server" copy:

无法连接更新服务器。GitHub API rate limit reached (HTTP 403) — try again in an hour.

"Check now" reproduces it; the state clears only when the IP's hourly bucket refills.

Root cause

apps/desktop/electron/main.tscheckUpdatesViaApi() asks api.github.com for the branch tip SHA, and fetchGitHubApi() sends only:

headers: {
  Accept: accept,
  'User-Agent': 'hermes-desktop-update-check'
}

No Authorization. GitHub's anonymous REST budget is 60 requests/hour per client IP, so a single shared exit (office NAT, VPN, a proxy node serving many users) exhausts it for everyone behind it — and the retry advice cannot help, because the next hour is spent by the same neighbours. The reason string is the only place the real cause appears (API rate limit exceeded for <ip>), and the panel does not surface it.

Same class as the Python side already handles: tools/skills_hub_github.py::GitHubAuth resolves GITHUB_TOKEN/GH_TOKEN, then gh auth token, then anonymous — the desktop's update check is the one GitHub client in the tree that never authenticates.

Evidence

Exit IP 209.240.29.134, anonymous:

$ curl -s -o /dev/null -w '%{http_code}\n' https://api.github.com/repos/NousResearch/hermes-agent/commits/main
403
$ curl -s https://api.github.com/rate_limit   # core remaining
0 / 60, resets at :25

With any credential the same request is served from a 5,000/hour budget.

Expected

The update check should use the credentials the machine already has (GITHUB_TOKEN/GH_TOKEN, or the gh CLI login) before falling back to the anonymous budget — the same ladder as the Python client. A GUI-launched app needs the gh rung specifically, since it inherits a minimal environment; env vars alone leave the affected users unchanged.

Workaround today

Wait for the hourly reset, switch the exit IP (different proxy node / direct), or force the check from the CLI. Note the actual update path (hermes update) is unaffected — it uses git, not the REST API — so this is the passive check only.

/cc fix proposed in a follow-up PR.

Source: NousResearch/hermes-agent