Bulk deleting spam GitHub Issues
Posted by christian on 03 April 2026
This morning I woke up to find almost 300 emails relating to issues raised on one of my public GitHub repositories. Deleting the emails is relatively straightforward in GMail but the GitHub website provides no way to bulk-delete issues (it can be done one-by-one, but this is not an option for so many of them). So, for future reference (by myself if no one else), here's what to do:
- Install GitHub's command line interface (CLI) tool, which provides the
ghcommand. I'm on a Mac, sobrew install ghworked for me. - Get a fine-grained Personal Access Token (PAT) with Repository Access and Repository Permissions: Issues set to Read and write. The actual GitHub account attached to the PAT must have an Admin or Owner role in the repository.
- Clone the repository locally if it isn't already there.
- From within the cloned repository authenticate to GitHub with the command
gh auth loginusing the PAT when prompted. - You can view up to 1000 open issues with
gh issue list --state open --limit 1000. - To delete issues via the API, your token specifically needs the
delete_reposcope. By default, theghCLI doesn't request this permission to keep your account safe from accidental deletions. So rungh auth refresh -s delete_repoand authenticate in a browser to grant the necessary permission. - Finally, run the following command to delete each open issue. Note that it does not discriminate between spam issues and other issues: every open issue (up to the
limit) will be deleted; you many need further filters if this is not the outcome you want.
gh issue list --state open --limit 1000 --json number -q '.[].number' | xargs -I {} gh issue delete {} --yes
The command does the following:
gh issue list --state open: Filter the repository's issues to only show the ones that are currently open.--limit 1000: The CLI defaults to only fetching 30 items at a time: any spammer worth his salt will be sending more than that, so increase the limit to 1000.--json number -q '.[].number': Extract just the raw issue numbers into a clean list, skipping all the titles and metadata.| xargs -I {} ... :Take that list of issue numbers and feed them one by one into the next command.gh issue delete {} --yes: Delete the specific issue. The--yesflag skips the interactive confirmation prompt so the process can run without user intervention.