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-pythonfetchesversions-manifest.jsonfromactions/python-versionsand 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 whateverpythonhappens to be onPATH(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:
GET https://api.github.com/repos/actions/python-versions/git/trees/mainto find the blob URL forversions-manifest.json.GET <that blob URL>withAccept: application/vnd.github.VERSION.rawto get the manifest body.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:
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 thesetup-pythonstep that anything went wrong.Captured truncated
versions-manifest.jsonfrom last week:20260522T135554Z-manifest.json
20260522T134810Z-manifest.json
20260522T125459Z-manifest.json