github/github-mcp-server · error
failed to get latest release: %w
Error message
failed to get latest release: %w
What it means
Returned by get_latest_release when client.Repositories.GetLatestRelease (GET /repos/{owner}/{repo}/releases/latest) fails. GitHub answers 404 both for an unknown repo and - very commonly - for a repo that simply has no published (non-draft) release yet, so 404 is the dominant trigger. The handler wraps with a bare fmt.Errorf instead of the structured ghErrors mapping used by neighbors, so the status code lives only in the wrapped *github.ErrorResponse; 401 (expired token) and 403 (rate limit) also surface here.
Source
Thrown at pkg/github/repositories.go:1955
[]scopes.Scope{scopes.Repo},
func(ctx context.Context, deps ToolDependencies, _ *mcp.CallToolRequest, args map[string]any) (*mcp.CallToolResult, any, error) {
owner, err := RequiredParam[string](args, "owner")
if err != nil {
return utils.NewToolResultError(err.Error()), nil, nil
}
repo, err := RequiredParam[string](args, "repo")
if err != nil {
return utils.NewToolResultError(err.Error()), nil, nil
}
client, err := deps.GetClient(ctx)
if err != nil {
return nil, nil, fmt.Errorf("failed to get GitHub client: %w", err)
}
release, resp, err := client.Repositories.GetLatestRelease(ctx, owner, repo)
if err != nil {
return nil, nil, fmt.Errorf("failed to get latest release: %w", err)
}
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode != http.StatusOK {
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, nil, fmt.Errorf("failed to read response body: %w", err)
}
return ghErrors.NewGitHubAPIStatusErrorResponse(ctx, "failed to get latest release", resp, body), nil, nil
}
r, err := json.Marshal(release)
if err != nil {
return nil, nil, fmt.Errorf("failed to marshal response: %w", err)
}
result := utils.NewToolResultText(string(r))
// Releases are published by collaborators with push access, soView on GitHub (pinned to 0ea1f775a7)
Solutions
- Confirm a published release exists: `gh api repos/OWNER/REPO/releases --jq '[.[] | select(.draft==false)] | length'`.
- If zero: switch to list_releases and treat the empty list as 'no releases'.
- 404 despite releases: fix owner/repo spelling or grant the token repo access.
- 401/403: refresh the token / wait out the rate-limit window.
Example fix
// caller: treat 404 as 'no release yet' instead of a hard failure
const res = await client.callTool({ name: 'get_latest_release', arguments: { owner, repo } });
if (res.isError && /failed to get latest release/.test(JSON.stringify(res.content))) {
const list = await client.callTool({ name: 'list_releases', arguments: { owner, repo } });
// parse list; empty -> report 'no published releases'
} Defensive patterns
Strategy: validation
Validate before calling
# get_latest_release 404s until a non-draft release exists - check first gh api 'repos/OWNER/REPO/releases?per_page=100' --jq '[.[] | select(.draft == false)] | length' # 0 -> skip get_latest_release; call list_releases and treat [] as 'no releases'
Try / catch
const res: any = await client.callTool({ name: 'get_latest_release', arguments: { owner, repo } });
if (res.isError && /failed to get latest release/.test(JSON.stringify(res.content))) {
// 404 is expected for repos with no published release - fall back
const list: any = await client.callTool({ name: 'list_releases', arguments: { owner, repo } });
} Prevention
- Publish at least one release before wiring get_latest_release into pipelines.
- Treat 404 from this endpoint as 'no latest release', not an error path.
- Validate owner/repo with a cheap repo GET before release automation.
- Watch rate-limit headers when checking releases in loops.
When it happens
Trigger: Repo exists but has zero published releases (404 'Not Found'); only draft or prerelease-unpublished entries exist, since the latest endpoint never returns drafts; unknown/private-to-token repo (404); expired or revoked token (401); rate limit exhausted (403).
Common situations: Calling get_latest_release on a brand-new project before its first release; repos whose releases are all drafts; wrong owner/repo; CI token quota exhausted.
Related errors
- failed to list releases: %w
- failed to fetch raw content: %s
- failed to list repository security advisories: %w
- failed to query repository metadata: %w
- %s: %w
AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15).
Data as JSON: /api/errors/b59ff2dd4a1928a0.
Report an issue: GitHub.