Delete a GitHub Release without Losing the Tag

Deleting a release is a one-way door, and gh release delete gives you exactly one extra decision on the way through: whether the tag dies with it. This guide checks the target repository before anything changes, then walks through the delete itself. Allow about ten minutes, plus time to confirm the release is genuinely disposable. You need an authenticated gh installation and permission to delete releases in the target repository.

This guide describes the command installed on this machine: gh reports version 2.87.3. The Debian package database reports gh 2.45.0-1ubuntu0.3+esm3, so the executable and package metadata do not describe the same build. Check your own binary before relying on a different flag set.

1. Check the installed command

Read the command's local help first. This is a read-only step and does not need elevated privileges:

$ gh --version
gh version 2.87.3 (2026-02-23)
$ gh release delete --help
Delete a release

USAGE
  gh release delete <tag> [flags]

The command takes a release tag as its required argument. Its two operation-specific flags are --cleanup-tag, which also deletes that tag, and --yes or -y, which skips confirmation. The repository selector is inherited from the parent command and accepts [HOST/]OWNER/REPO through --repo or -R.

Checkpoint: if your installed help does not show the same syntax, stop and follow that help rather than copying this article blindly.

2. Confirm the target repository and release tag

Deleting a release is destructive. The tag is the key detail, and a familiar tag such as v1.2.3 can exist in several repositories. Write the complete repository and exact tag into a shell variable, then inspect the release before deleting it:

$ REPO='OWNER/REPOSITORY'
$ TAG='v1.2.3'
$ gh release view "$TAG" --repo "$REPO"
title: Example release
tag:    v1.2.3
...

Replace both uppercase placeholders. Do not use a value copied from an issue title or an untrusted message without checking it. If the release view command says the release cannot be found, do not retry with a guessed tag: check spelling, host, owner and repository name first.

Recovery: save any release notes, asset names or links you will need later before deleting. The delete command has no undo option in its manual, so keep the source code and any tag or release metadata you may need to recreate the release.

3. Decide what happens to the tag

By default, gh release delete deletes only the release named by the tag. The manual describes --cleanup-tag as an additional action: it deletes the specified tag as well. That distinction matters when the tag is used by a build, deployment, changelog or another workflow.

For the safer default, leave the tag in place:

$ gh release delete "$TAG" --repo "$REPO"
? Are you sure you want to delete the release v1.2.3 from OWNER/REPOSITORY? (y/N)

Answer the confirmation prompt only after checking the repository and tag shown. A refusal leaves the release unchanged. Keeping the tag does not restore the deleted release object, but it preserves the named Git reference for later investigation or recreation.

If the tag itself is also disposable, use the explicit cleanup flag:

$ gh release delete "$TAG" --repo "$REPO" --cleanup-tag
? Are you sure you want to delete the release v1.2.3 from OWNER/REPOSITORY? (y/N)

Warning: do not add --cleanup-tag merely to make the command look complete. It changes the Git repository as well as the release, and may disrupt anything that fetches the tag.

4. Use non-interactive deletion only when the target is fixed

Automation can skip the prompt with --yes or -y. Use it only when the repository and tag come from a controlled, reviewed input, and quote variables as shown:

$ gh release delete "$TAG" --repo "$REPO" --yes

For a one-off deletion, the prompt is a useful last checkpoint. In a script, validate the repository and tag before this command, log the exact target, and fail closed when either value is empty. Never build the command by concatenating unchecked user input into an option string.

5. Verify the result and handle failure

Run the same read-only lookup after a successful deletion:

$ gh release view "$TAG" --repo "$REPO"
release not found

The exact error wording can vary by GitHub CLI version, so the useful check is a failed lookup for the exact repository and tag. If you used --cleanup-tag, separately check the tag through your normal GitHub or Git workflow before assuming it is gone. If you did not use that flag, confirm the tag still exists, if it is meant to remain.

An authentication or permission error does not prove the release was deleted. Fix the account, host, repository or permission issue, then repeat the inspection step before retrying. Do not switch to --yes as a diagnostic shortcut. If the release has already been deleted, the command cannot restore it: recreate it only from preserved notes, assets and source history.

Done means