Description:
When actions/setup-python fetches versions-manifest.json from actions/python-versions and GitHub's API returns a truncated body, the action parses it as an empty release list and exits 0 without installing Python. The step is reported successful, and subsequent job steps run against whatever python happens to be on PATH (if any) - which makes the real cause harder to find.
Action version:
v6.2.0 (also affects earlier versions - the manifest-fetch logic is unchanged regarding such edge cases).
Platform:
Runner type:
Tools version:
All Python versions - the failure is in the manifest fetch, before any version-specific logic runs.
Repro steps:
Hard to reproduce on demand now that the upstream GitHub-side issue appears to be resolved, but here is what I saw last week:
- The action fetches the manifest in two calls:
- GET https://api.github.com/repos/actions/python-versions/git/trees/main to find the blob URL for versions-manifest.json.
- GET <that blob URL> with Accept: application/vnd.github.VERSION.raw to get the manifest body.
- Sporadically, the second call returned a truncated body - HTTP 200, but the JSON was cut off mid-object and unparseable. I captured 3 separate examples (attached - please see them at the bottom).
- Two odd characteristics of the bad responses:
- A ~30 second server-side delay before any bytes came back.
- Only reproduced on authenticated requests. Anonymous requests always returned the full manifest - but the 60 req/hour anon limit is too low for real CI use (authenticated is 5000/hour).
Expected behavior:
If the manifest body is empty, truncated, or not a valid releases array, the action should fail loudly (ideally after a few retries with backoff), not exit 0 without installing Python. Suggested fix:
- After fetching, validate that the body parses as JSON and is a non-empty array of releases.
- Retry with backoff on failure - these truncations were intermittent and a retry would almost certainly succeed.
- If retries are exhausted, core.setFailed() with a clear "manifest fetch/parse failed" message.
Actual behavior:
A truncated manifest response is silently swallowed: it does not install Python, and exits 0. The job continues against the system python (or fails much later in a confusing way), and there is no signal in the setup-python step that anything went wrong.
* Installed versions
##[debug]Semantic version spec of 3.11 - 3.13 is 3.11 - 3.13
##[debug]isExplicit:
##[debug]explicit? false
##[debug]evaluating 0 versions
##[debug]match not found
Version 3.11 - 3.13 was not found in the local cache
##[debug]Getting manifest from actions/python-versions@main
##[debug]set auth
##[debug]Node Action run completed with exit code 0
##[debug]Finishing: Setup python
Captured truncated versions-manifest.json from last week:
20260522T135554Z-manifest.json
20260522T134810Z-manifest.json
20260522T125459Z-manifest.json
Description:
When actions/setup-python fetches versions-manifest.json from actions/python-versions and GitHub's API returns a truncated body, the action parses it as an empty release list and exits 0 without installing Python. The step is reported successful, and subsequent job steps run against whatever python happens to be on PATH (if any) - which makes the real cause harder to find.
Action version:
v6.2.0 (also affects earlier versions - the manifest-fetch logic is unchanged regarding such edge cases).
Platform:
Runner type:
Tools version:
All Python versions - the failure is in the manifest fetch, before any version-specific logic runs.
Repro steps:
Hard to reproduce on demand now that the upstream GitHub-side issue appears to be resolved, but here is what I saw last week:
Expected behavior:
If the manifest body is empty, truncated, or not a valid releases array, the action should fail loudly (ideally after a few retries with backoff), not exit 0 without installing Python. Suggested fix:
Actual behavior:
A truncated manifest response is silently swallowed: it does not install Python, and exits 0. The job continues against the system python (or fails much later in a confusing way), and there is no signal in the setup-python step that anything went wrong.
Captured truncated versions-manifest.json from last week:
20260522T135554Z-manifest.json
20260522T134810Z-manifest.json
20260522T125459Z-manifest.json