Skip to content

fix(gui): survive GitHub API rate limits; don't wipe existing install before a verified download - #28

Open
edufalcao wants to merge 1 commit into
SteamDeckHomebrew:mainfrom
edufalcao:fix/api-rate-limit-safe-install
Open

fix(gui): survive GitHub API rate limits; don't wipe existing install before a verified download#28
edufalcao wants to merge 1 commit into
SteamDeckHomebrew:mainfrom
edufalcao:fix/api-rate-limit-safe-install

Conversation

@edufalcao

Copy link
Copy Markdown

Fixes #16. Full root-cause investigation in SteamDeckHomebrew/decky-loader#940 (also the resurfaced reports in SteamDeckHomebrew/decky-loader#492).

Problem

When the GitHub API rate-limits an IP (60 unauthenticated requests/hour, shared by everyone behind the same CGNAT/proxy IP), the GUI installer:

  1. gets an error object instead of a release array, producing jq: error ... Cannot index string with string "prerelease";
  2. ends up with an empty $DOWNLOADURL, so PluginLoader is never downloaded (chmod: cannot access .../PluginLoader);
  3. still reports "Install finished, installer can now be closed";
  4. and, worst, has already run rm -rf "${HOMEBREW_FOLDER}/services" before contacting the API — so trying to update a working install destroys it.

Changes (gui/user_install_script.sh only)

  1. Release channel no longer uses the GitHub API at all. The latest tag is resolved from the releases/latest redirect (location: header) and the asset is fetched from releases/download/<tag>/PluginLoader. Neither endpoint is rate-limited — verified working from an IP whose API quota was exhausted (403, x-ratelimit-remaining: 0) at that exact moment. This makes default installs immune to the rate limit. The prerelease channel still needs the API (GitHub has no "latest prerelease" redirect).
  2. Validate VERSION/DOWNLOADURL before touching anything. If empty/null (rate limit, API change, network failure), show a zenity error explaining the likely rate limit and exit — the existing install is left intact. Previously the failure was invisible to GUI users since it only went to stdout.
  3. Download to a temp file first; wipe/replace services/ only after a verified download (curl exit code via PIPESTATUS + non-empty file check, curl -f so HTTP errors fail instead of saving an error page). This is the ordering fix suggested in install script is not working when api returns rate limit #16 — a failed update can no longer delete a working install.

Note: chmod +x became chmod 755 because mktemp creates files as 600; 755 preserves the exact permissions the installed binary had before this change.

Testing

  • bash -n passes.
  • Release-path resolution tested live while the network's API quota was exhausted: resolves v3.2.6, asset URL answers HTTP 200 (~27 MB).
  • Prerelease path tested live against the rate-limited API: validation aborts before rm -rf.
  • Download guard tested against a 404 asset URL: triggers correctly.
  • Not yet tested on real SteamOS hardware end-to-end (my Legion Go is the affected device; happy to run the branch script on it if wanted).

🤖 Generated with Claude Code

https://claude.ai/code/session_01FCRmEjYtRFKUVG36VsN9ay

…tact until download succeeds

- Resolve the latest release tag via the releases/latest redirect instead
  of the GitHub API, which is rate-limited to 60 unauthenticated
  requests/hour per IP (shared across CGNAT users). The release channel
  no longer touches api.github.com at all.
- Validate VERSION/DOWNLOADURL and abort with a visible zenity error
  before deleting the existing services folder, instead of silently
  continuing to a broken 'Install finished' state.
- Download PluginLoader to a temp file first and only wipe/replace the
  existing install after the download is verified.

Fixes SteamDeckHomebrew#16

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FCRmEjYtRFKUVG36VsN9ay
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

install script is not working when api returns rate limit

1 participant