The release title has a typo, or the notes need one more line, and gh release edit changes it without deleting and recreating the release. The examples use GitHub CLI 2.87.3, selected from Homebrew on this machine. The Ubuntu package database also contains gh 2.45.0-1ubuntu0.3+esm3; check gh version in your own shell so that you know which executable is actually first in PATH.
Allow about ten minutes for a routine edit. You need an authenticated gh installation, access to the repository, and the exact release tag. These commands change the release on GitHub. They do not need sudo, and running them as root will not grant repository access that your account does not have.
Start with read-only checks. Use the repository argument when your current directory is not a checkout of the project:
$ gh version
gh version 2.87.3 (2026-02-23)
$ gh release edit --help
$ gh auth status
$ REPO='OWNER/REPO'
$ TAG='v1.2.3'
Replace OWNER/REPO and v1.2.3 with real values. The command's syntax is gh release edit <tag>. Keep the tag as one shell word and quote variables when using them. If gh auth status reports the wrong account or host, stop and fix authentication before changing anything.
Checkpoint: You have an exact tag and have confirmed that the selected account can work on the intended host.
Take a small, readable snapshot immediately before the edit. This is your recovery reference if the new values are wrong:
$ gh release view "$TAG" --repo "$REPO" \
--json tagName,name,body,isDraft,isPrerelease,targetCommitish
{
"tagName": "v1.2.3",
"name": "Previous title",
"body": "Existing release notes",
"isDraft": false,
"isPrerelease": false,
"targetCommitish": "main"
}
The displayed values are examples. Save the output somewhere private if the notes are sensitive or long. The JSON field names above are provided by the installed gh release view command; a different CLI version may offer a different field set. If the tag is missing, verify the repository and spelling rather than trying a nearby tag.
Use the smallest command that expresses the intended change. A title update is an ordinary release edit, but it is still a remote state change:
$ gh release edit "$TAG" --repo "$REPO" \
--title 'Maintenance release'
To replace the notes from a file, use --notes-file or its short form -F:
$ test -r release-notes.md && \
gh release edit "$TAG" --repo "$REPO" \
--notes-file release-notes.md
The test prevents an absent file from being passed by mistake. Read the file once before running the edit, especially if it was generated by another command. A notes edit replaces the release notes with the file content, so keep the old body from step 2 until the new release has been checked.
Three state flags are easy to confuse:
--draft saves the release as a draft. The documented way to publish a draft with this command is --draft=false.--prerelease marks the release as a prerelease.--latest explicitly marks it as Latest.$ gh release edit "$TAG" --repo "$REPO" --draft=false
Publishing a draft may notify users or make assets visible. Treat it as an intentional publication step, not as a harmless verification command. Set the prerelease and latest flags only when that channel decision is part of the change. Do not add them to a copy-and-paste command merely because they are available.
Warning: A release edit is not a local transaction with an automatic undo. Publishing, changing the Latest designation, or replacing notes can affect people and automation immediately. Confirm the tag, repository and desired values immediately before pressing Enter.
The normal form edits the release identified by the positional tag. The inherited --repo option selects another repository using HOST/OWNER/REPO or OWNER/REPO. The command also accepts --target for a branch or full commit SHA, with the main branch as its documented default, and --verify-tag to abort when the Git tag does not already exist in the remote repository:
$ gh release edit "$TAG" --repo "$REPO" \
--target main --verify-tag
Use --target when the release must point at a particular branch or commit. Use --verify-tag as a guard when a typo or accidental tag creation would be unacceptable. The --tag option is separate from the positional argument, so do not include it unless you have a specific tag-name change to make and have checked the command's behaviour for your release workflow.
Read the release again using the same repository and tag:
$ gh release view "$TAG" --repo "$REPO" \
--json tagName,name,body,isDraft,isPrerelease,targetCommitish
{
"tagName": "v1.2.3",
"name": "Maintenance release",
"body": "Existing release notes",
"isDraft": false,
"isPrerelease": false,
"targetCommitish": "main"
}
Compare the result with your intended change, not just the exit status. If notes contain markup or line breaks, inspect the complete body rather than relying on a truncated terminal view. A non-zero status means the edit did not complete normally, but still check the release before retrying: a network failure can leave you uncertain about whether the remote accepted the request.
Recovery: there is no separate rollback command. Re-run gh release edit with the values recorded in step 2. For a notes rollback, use the saved original notes file:
$ gh release edit "$TAG" --repo "$REPO" \
--title 'Previous title' \
--notes-file previous-release-notes.md
$ gh release view "$TAG" --repo "$REPO" \
--json tagName,name,body,isDraft,isPrerelease,targetCommitish
For a publication mistake, set the draft state back only after checking your repository's release policy. Do not delete the release or tag as a recovery shortcut. Deletion is a different, more destructive operation and is outside this guide.
gh version identified the executable and you checked authentication.gh release view.