{"record":{"id":"69eb8bb055d4a796","repo":"cli/cli","slug":"release-not-found","errorCode":null,"errorMessage":"release not found","messagePattern":"release not found","errorType":"http","errorClass":"ErrReleaseNotFound","httpStatus":404,"severity":"error","filePath":"pkg/cmd/release/shared/fetch.go","lineNumber":133,"sourceCode":"\t\t\t\t\t\"digest\":        a.Digest,\n\t\t\t\t\t\"state\":         a.State,\n\t\t\t\t\t\"createdAt\":     a.CreatedAt,\n\t\t\t\t\t\"updatedAt\":     a.UpdatedAt,\n\t\t\t\t\t\"downloadCount\": a.DownloadCount,\n\t\t\t\t\t\"contentType\":   a.ContentType,\n\t\t\t\t})\n\t\t\t}\n\t\t\tdata[f] = assets\n\t\tdefault:\n\t\t\tsf := fieldByName(v, f)\n\t\t\tdata[f] = sf.Interface()\n\t\t}\n\t}\n\n\treturn data\n}\n\nvar ErrReleaseNotFound = errors.New(\"release not found\")\n\ntype fetchResult struct {\n\trelease *Release\n\terror   error\n}\n\nfunc FetchRefSHA(ctx context.Context, httpClient *http.Client, repo ghrepo.Interface, tagName string) (string, error) {\n\turl, err := safeurl.JoinPathWithHostPrefix(ghinstance.RESTPrefix(repo.RepoHost()), \"repos\", repo.RepoOwner(), repo.RepoName(), \"git\", \"ref\", fmt.Sprintf(\"tags/%s\", tagName))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treq, err := http.NewRequestWithContext(ctx, \"GET\", url.String(), nil)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tresp, err := httpClient.Do(req)\n\tif err != nil {","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/cli/cli/blob/0eeec0b92edbe70199f9768522f831d3534f41ad/pkg/cmd/release/shared/fetch.go#L115-L151","documentation":"Sentinel error (shared.ErrReleaseNotFound) in the release shared package. It is returned when a REST lookup of a release, or of the git tag ref backing it, responds with HTTP 404 - meaning no release with that tag exists on the repo (or is visible to your credentials). Because it is a package-level sentinel, callers match it with errors.Is, e.g. `gh release create` checks it to decide whether to create a new release or update an existing one.","triggerScenarios":"Any FetchRelease/FetchRefSHA call where GitHub returns 404: wrong tag name, release not yet created, a draft release on a repo your token cannot see (drafts require write access), or querying the wrong repository/host.","commonSituations":"Release automation scripts assuming the release exists; read-only tokens trying to view draft releases; typos in the tag; a fork where the release lives on the upstream repo. Note create/http.go intentionally treats this error as 'release does not exist yet, proceed to create'.","solutions":["Verify the tag and repo: gh release list -R owner/repo, or gh release view <tag>","For draft releases, authenticate with an account that has push access to the repo","If you are writing automation, check errors.Is(err, shared.ErrReleaseNotFound) and branch to create vs update logic like gh itself does"],"exampleFix":"// before\nrel, err := shared.FetchRelease(ctx, client, repo, \"v1.2.3\")\nif err != nil { return err }\n// after\nrel, err := shared.FetchRelease(ctx, client, repo, \"v1.2.3\")\nif errors.Is(err, shared.ErrReleaseNotFound) {\n    // create it instead\n} else if err != nil { return err }","handlingStrategy":"try-catch","validationCode":"// Cheap existence probe before heavy logic:\nout, err := ghapi(fmt.Sprintf(\"repos/%s/%s/releases/tags/%s\", owner, repo, tag))\nif err != nil { /* 404 means the release does not exist yet */ }","typeGuard":null,"tryCatchPattern":"rel, err := shared.FetchRelease(ctx, client, repo, tag)\nswitch {\ncase err == nil:\n    // update path\ncase errors.Is(err, shared.ErrReleaseNotFound):\n    // create path (this is exactly what gh release create does)\ndefault:\n    return err // real network/auth failure\n}","preventionTips":["Always branch on errors.Is(err, shared.ErrReleaseNotFound) rather than string matching","Use write-access tokens when scripts must see draft releases","Verify tag spelling and -R owner/repo before release automation runs"],"tags":["release","http-404","sentinel-error","authentication"],"backgroundTag":null,"analyzedSha":"0eeec0b92edbe70199f9768522f831d3534f41ad","analyzedAt":"2026-08-15T12:31:05.478Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}