Skip to content

Bug: get_assets() fails with 404 when release is fetched by tag in v2.9.0 #3467

@SebastienSyd

Description

@SebastienSyd

Bug: get_assets() fails with 404 when release is fetched by tag in PyGithub 2.9.0

Summary

In PyGithub 2.9.0, when a release is fetched by tag name using repo.get_release("v1.2.3"), calling release.get_assets() results in a 404 error because the constructed URL is invalid.

Root Cause

PyGithub 2.9.0 introduced lazy loading for releases (PR #3403). When fetching a release by tag:

  1. The code constructs a lazy object with URL: https://api.github.com/repos/owner/repo/releases/tags/TAG_NAME
  2. The __postProcess method in Requester.py sets data["url"] to this GET URL (line 883)
  3. The get_assets() method constructs the assets URL as f"{self.url}/assets"
  4. This results in: https://api.github.com/repos/owner/repo/releases/tags/TAG_NAME/assets
  5. This is not a valid GitHub API endpoint - it should be: https://api.github.com/repos/owner/repo/releases/RELEASE_ID/assets

Reproduction

from github import Github

gh = Github(auth=...)  # Use authenticated client
repo = gh.get_repo("owner/repo")

# Get release by tag
release = repo.get_release("v1.2.3")

# This fails with 404
assets = list(release.get_assets())

Expected Behavior

The release.url property should contain the canonical release URL with the numeric release ID, not the /tags/TAG_NAME URL used to fetch it.

Actual Behavior

github.GithubException.UnknownObjectException: 404 {"message": "Not Found", ...}

Workaround

Get the release by ID instead of by tag:

# Get the release ID first
releases = repo.get_releases()
for r in releases:
    if r.tag_name == "v1.2.3":
        release = repo.get_release(r.id)
        break

Suggested Fix

In Requester.py, the __postProcess() method should:

  1. Check if the response contains an id field
  2. If URL ends with /releases/tags/{tag}, reconstruct it as /releases/{id}
  3. Set data["url"] to the canonical URL

Alternatively, ensure the GitHub API response always includes the proper url field, and only fallback to the request URL if it's missing.

Environment

  • PyGithub version: 2.9.0
  • Python version: 3.11+
  • Works correctly in: PyGithub 2.8.1

Impact

This bug affects any code that:

  • Fetches releases by tag name (common pattern)
  • Attempts to download release assets
  • Uses GitHub App authentication with private repositories (where assets require authentication)

Related Changes

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions