fix(updates): reject GitHub HTTP error payloads - #3167
Open
tang-vu wants to merge 1 commit into
Open
Conversation
This was referenced Aug 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why this matters
All three dashboard consumers of the GitHub Releases API parse JSON without first checking the HTTP status. A rate-limit response (403) is therefore treated as a valid latest-release payload and replaces useful stale cache data with an empty version for five minutes. The update dry-run reports no update and no error. The manifest path also accepts any list-shaped JSON body from a failing proxy as real releases.
This calls
raise_for_status()before parsing the latest-release cache, release manifest, and dry-run responses. Existing narrowhttpx.HTTPErrorboundaries then preserve stale cache data or return the documented local-version fallback/error field instead of manufacturing a successful no-update result.Behavioral invariant: only a successful GitHub HTTP response may update release metadata; non-2xx responses must preserve last-known-good state or be surfaced through the endpoint fallback contract.
Overlap check
Searched open and closed PRs for
GitHub release API raise_for_status,release rate limit dashboard update, and the changed production fileods/extensions/services/dashboard-api/routers/updates.py. No PR covers HTTP-status validation at these call sites.Existing tests covered connection exceptions and non-list manifest bodies but not valid JSON delivered with a non-success status. This PR extends that existing router suite rather than adding another release client.
Regression test
tests/test_updates.pyadds three concrete contracts:/api/update/dry-runreports the 403 instead of silently returning a clean no-update result; and/api/releases/manifestrejects a list-shaped JSON body delivered with HTTP 503 and falls back to the installed version.Before the fix, the cache test was replaced by an empty payload and the dry-run error field was null; the 503 list was published as version 999.0.0.
Validation
python -m pytest tests/test_updates.py -q? 32 passedpython -m compileall -q routers/updates.py tests/test_updates.py? passedmake lint? passedgit diff --check? passedThe suite uses real
httpx.Responsestatus behavior behind deterministic mocked transport and exercises the public FastAPI endpoints for dry-run and manifest. No live GitHub rate limit or outage was induced. Rollback only restores the permissive parser and requires no persisted-data migration.Batch compatibility
This PR was validated on synthetic integration head
9af795fc, which applies #3158 through #3167 in numeric order onupstream/main(6ff9b4fc). Combinedmake lint,make test,make smoke,make simulate, and all 418 BATS cases passed (one root-specific permission assertion skipped by design).Recommended merge order: #3158 ? #3159 ? #3160 ? #3161 ? #3162 ? #3163 ? #3164 ? #3165 ? #3166 ? #3167. The only manual reconciliation observed was the adjacent Makefile test insertion shared by #3164 and #3166; retain both
test-unix-restart-recreate-env.shandtest-chat-error-exit-parity.shlines. Production code merged automatically across the full batch.