gh release upload: Usage, Options & Common CI Errors
Attach build artifacts to an existing GitHub release.
gh release upload adds asset files to a release that already exists - useful when assets are built after the release is created or by a separate matrix job.
What it does
gh release upload <tag> <files...> uploads one or more files as assets on the release for that tag. --clobber overwrites an asset with the same name (otherwise it errors), and you can rename an asset on upload with the file#display-name syntax.
Common usage
# Upload assets to an existing release
gh release upload v1.2.0 ./dist/app-linux ./dist/app-macos
# Overwrite an asset that already exists
gh release upload v1.2.0 ./dist/app-linux --clobber
# Upload with a friendly display name
gh release upload v1.2.0 'build.zip#App (Linux x64)'Common error in CI: asset already exists / release not found
gh release upload fails with "asset already exists" when a matrix job re-uploads the same filename, or "release not found" when the tag has no release yet. Fix: pass --clobber to replace existing assets idempotently, and make sure gh release create <tag> ran before any upload job (or gate uploads on the create step). Unique per-platform filenames also avoid collisions across matrix jobs. Token needs contents: write.
Key options
| Option | Purpose |
|---|---|
| <tag> <files...> | Release tag and files to attach |
| --clobber | Overwrite assets with the same name |
| file#name | Set a display name for an asset |