Safely Edit a GitHub Release with gh release edit
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.
The route
Jump straight to the step you need, or tick off Done means at the end.
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.
1. Check the executable and repository
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.
2. Record the current release
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.
3. Change one release property
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.
4. Change draft and release-channel state deliberately
Three state flags are easy to confuse:
--draftsaves the release as a draft. The documented way to publish a draft with this command is--draft=false.--prereleasemarks the release as a prerelease.--latestexplicitly 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.
5. Use a target or alternate tag only when required
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.
6. Verify the remote result
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.
7. Recover from an incorrect edit
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.
Done means
- Identified correctly:
gh versionidentified the executable and you checked authentication. - Target confirmed: you verified the exact repository and release tag before editing.
- Old values recorded: you recorded the old title, notes and state.
- Narrowest flag used: you used the narrowest relevant edit flag and understood its remote effect.
- Result verified: you verified the resulting release with
gh release view. - Restorable: you still have the original values needed to restore an unwanted change.