Home / Alt manpages / gh-release-delete-asset(1)

  • gh-release-delete-asset(1)
  • User command
  • linux

Delete One GitHub Release Asset Safely with gh

You will remove one named asset from a GitHub release using the installed GitHub CLI, then confirm that it is no longer listed. This is a destructive remote operation: deleting the asset does not remove the release or its tag, but the asset itself is not restored by the command.

Before you start

Allow about five minutes if you already know the repository, release tag and asset name. You need:

  • gh installed and authenticated for the target GitHub host.
  • permission to administer releases in the repository.
  • the exact release tag, such as v2.4.0.
  • the exact asset name, including its case and file extension.

This guide was checked with GitHub CLI 2.87.3, released on 23 February 2026. The local command is gh release delete-asset <tag> <asset-name>. Its command-specific options are --yes (or -y) and the inherited --repo (or -R).

Checkpoint: identify the target

First decide whether the command should use the repository in your current directory or an explicit repository. An explicit --repo is safer when you are working from a clone that could point at the wrong remote.

Set the values in this example to real values before running it. The shell variables do not change GitHub; they only make the later commands easier to inspect.

repo="OWNER/REPOSITORY"
tag="v2.4.0"
asset="example-linux-amd64.tar.gz"

printf 'repository: %s
release tag: %s
asset: %s
' "$repo" "$tag" "$asset"

Check the release and print its asset names:

gh release view "$tag" --repo "$repo"   --json assets --jq '.assets[].name'

Expected output is one asset name per line. Do not continue until the line for $asset matches exactly. If the command reports that the release cannot be found, check the repository owner, repository name and tag. A tag is not interchangeable with a release title.

Checkpoint: confirm the repository context

If you chose to use the current directory instead of --repo, inspect the repository context before deleting anything:

gh repo view --json nameWithOwner --jq '.nameWithOwner'

It should print the repository you intended to change. The delete command accepts an optional host prefix in the repository value, so a GitHub Enterprise target can use a form such as ghe.example/OWNER/REPOSITORY when that host is configured in gh.

Delete the asset with a confirmation prompt

Run the command without --yes first. This keeps a final confirmation between your inspection and the destructive request.

gh release delete-asset "$tag" "$asset" --repo "$repo"

Review the prompt carefully. It should refer to the release identified by your tag and the asset name you checked. Confirm only if both are correct. A successful request normally returns without a lengthy result, so use the verification step below rather than treating a quiet terminal as proof.

No elevated Linux privileges are required. Do not prefix this with sudo: the operation is authorised by your GitHub credentials, not by local filesystem permissions.

Automate a deletion only after testing it

For a reviewed script or a non-interactive job, --yes skips the confirmation prompt:

gh release delete-asset "$tag" "$asset" --repo "$repo" --yes

Use this only when the tag, asset and repository came from trusted, validated values. Never pass an unchecked filename or user-supplied string into a destructive command. If a script may run against more than one repository, require an explicit allow-list or an explicit repository argument rather than relying on the current directory.

Verify that the asset is gone

Query the same release again:

gh release view "$tag" --repo "$repo"   --json assets --jq '.assets[].name'

The deleted name should no longer appear. An empty response is valid when it was the release's only asset. To turn that check into a scriptable assertion, use:

if gh release view "$tag" --repo "$repo"     --json assets --jq '.assets[].name' | grep -Fxq "$asset"; then
  printf 'asset still present: %s
' "$asset" >&2
  exit 1
fi
printf 'asset absent: %s
' "$asset"

The command can fail before producing a useful asset list if authentication, repository access or the network is unavailable. Treat that as an unverified state and investigate before repeating a deletion. Repeating the delete request for an already removed name is not a recovery method.

Recovery and safer alternatives

gh release delete-asset has no undo flag. If you removed the wrong asset, recover it by uploading a retained local copy with the release upload command:

gh release upload "$tag" ./example-linux-amd64.tar.gz --repo "$repo"

This creates a new release asset from the local file. It is not a byte-for-byte recovery if the original file is unavailable, and it may not preserve every property of the old asset. Confirm the replacement with gh release view before treating the incident as resolved.

If your actual aim is to replace an asset, check the upload command's current behaviour first. Its --clobber option can delete and re-upload an existing asset with the same name, which is a different operation from deleting an asset and leaving the release without it. If you only want to hide a release, deleting an individual asset is the wrong scope: it does not delete the release, tag or other assets.

Common traps

  • Wrong repository: omitting --repo uses repository context inferred by gh. Print nameWithOwner when there is any doubt.
  • Wrong identifier: pass the release tag, not the release's display name. List the target release with gh release view before making changes.
  • Near-match asset name: asset names are not a glob here. Copy the exact value printed by the JSON query.
  • Assuming a local file is relevant: the asset argument names the remote release asset. It is not a path to a local file.
  • Skipping verification: a command that exits quietly still deserves a follow-up query, especially in automation.

Done means

  • The repository and release tag were checked explicitly.
  • The exact remote asset name was listed before deletion.
  • The confirmation prompt was accepted, or --yes was used only in a reviewed automation path.
  • A second release query shows that the asset name is absent.
  • A local replacement copy exists if recovery may be needed.