Cancel the Right GitHub Actions Run with gh run cancel
gh run cancel stops one GitHub Actions run by its numeric ID, so you are not guessing from a branch name or a half-loaded browser tab. The examples use GitHub CLI 2.87.3, installed here from Linuxbrew. Budget about ten minutes. You need an authenticated gh installation, access to the repository, and a run that is still eligible for cancellation.
The route
Jump straight to the step you need, or tick off Done means at the end.
Warning
Cancellation changes remote state. It can stop jobs mid-flight, leave partial artefacts, and interrupt a deployment or release workflow. Read the run details before you cancel it, and do not treat this command as a harmless local test. No sudo or other elevated privilege is needed; GitHub authorisation is the permission that matters here.
1. Check the installed command
Confirm which binary your shell will run and record its version:
$ command -v gh
/home/linuxbrew/.linuxbrew/bin/gh
$ gh --version
gh version 2.87.3 (2026-02-23)
The local gh-run-cancel(1) page documents the command shape and the inherited repository option. The installed command also advertises --force, so treat that flag as version-specific behaviour and use the installed help as the operational check.
Checkpoint
Make sure the version and path are the ones you expected. If gh is missing, fix the installation or shell path first; do not work around a missing binary by copying a token into a script.
2. Confirm authentication and repository scope
Check the account and host before looking for a run:
$ gh auth status
github.com
Logged in to github.com account YOUR_ACCOUNT
Git operations protocol: https
Token: ********
Your account name and status lines will differ. Treat a failed status check as a stopping point: authenticate through your normal approved method, then rerun the check. Keep access tokens out of command arguments, shell history and pasted output.
For a repository other than the current one, pass its full owner and repository name with -R or --repo:
$ gh run list --repo OWNER/REPOSITORY --limit 10
A relative repository such as OWNER/REPOSITORY is enough for GitHub.com. GitHub Enterprise hosts use HOST/OWNER/REPOSITORY. Use the same scope on the later view and cancel commands, so a copied ID cannot land on the wrong repository.
3. Find a run ID without choosing by eye
List a small, relevant set of runs. Filtering by workflow, branch or status cuts the chance of cancelling the wrong one:
$ gh run list --repo OWNER/REPOSITORY --workflow deploy.yml --branch main --status in_progress --limit 10
STATUS TITLE WORKFLOW BRANCH EVENT ID ELAPSED AGE
* Deploy production deploy main push 1234567890 2m about 2m ago
Column formatting and the available rows vary. The ID column holds the workflow run ID. A run can finish between this listing and the cancellation request, so check it again immediately before you change state.
If the workflow has a display name rather than a file name, use the exact value accepted by your installed gh run list --help. For a scriptable selection, request JSON and inspect it rather than parsing the human table:
$ gh run list --repo OWNER/REPOSITORY --workflow deploy.yml --status in_progress --limit 5 \
--json databaseId,displayTitle,status,headBranch,url
[{"databaseId":1234567890,"displayTitle":"Deploy production","status":"in_progress","headBranch":"main","url":"https://github.com/OWNER/REPOSITORY/actions/runs/1234567890"}]
Do not automatically pick the first row unless your workflow guarantees it is the intended run. Ambiguous selection is a reason to stop and inspect the list by hand.
4. Inspect the exact run
Use the ID and the same repository scope to verify the workflow, branch, commit and current status:
$ gh run view 1234567890 --repo OWNER/REPOSITORY --json databaseId,displayTitle,status,conclusion,headBranch,headSha,url
{"databaseId":1234567890,"displayTitle":"Deploy production","status":"in_progress","conclusion":null,"headBranch":"main","headSha":"COMMIT_SHA","url":"https://github.com/OWNER/REPOSITORY/actions/runs/1234567890"}
Compare the branch and commit with the change you mean to stop. The empty conclusion is normal while a run is in progress. If the status is already completed, do not send a cancellation request. If the run is a release, migration or deployment, check its own rollback procedure before you continue.
5. Cancel the verified run
Once the ID, repository and purpose match, run:
$ gh run cancel 1234567890 --repo OWNER/REPOSITORY
✓ Cancelled workflow run 1234567890
The exact confirmation text can vary with the CLI version. A successful command means the cancellation request was accepted; it does not mean every job stopped at that instant. There is no undo command for cancellation. If the work is needed again, use the repository's normal rerun or workflow dispatch process, after checking what partial work was left behind.
Use --force only when the normal cancellation does not complete and you understand the consequences:
$ gh run cancel 1234567890 --repo OWNER/REPOSITORY --force
Warning
This is a stronger, service-disrupting action. Do not put it in a blind retry loop. Confirm the run is still the intended one and that an abrupt stop is safer than letting the jobs finish.
6. Verify the final state
Query the same run until GitHub reports a terminal state:
$ gh run view 1234567890 --repo OWNER/REPOSITORY --json status,conclusion,updatedAt
{"status":"completed","conclusion":"cancelled","updatedAt":"2026-09-23T12:34:56Z"}
There can be a short delay between acceptance and the completed status. If it stays in progress, wait briefly and query again rather than issuing repeated cancellation requests. If it ends with another conclusion, record that result and inspect the run in the GitHub web interface or with gh run view 1234567890 --repo OWNER/REPOSITORY --verbose.
For a simple shell check, treat the JSON values as evidence rather than trusting a successful network request alone:
$ gh run view 1234567890 --repo OWNER/REPOSITORY --json status,conclusion
{"status":"completed","conclusion":"cancelled"}
Common traps
- Wrong repository. A numeric ID only means something with its repository context. Repeat
--repoon list, view and cancel. - Stale list. A run may finish or be replaced after
gh run list. Inspect the exact ID immediately before cancellation. - Wrong run attempt. A workflow may have multiple attempts.
gh run viewsupports--attemptwhen you need one particular attempt, but cancellation still targets the run ID. - Permissions or rate limits. An API error is not evidence that cancellation happened. Recheck the run state once authentication or connectivity is fixed.
- Partial side effects. Cancelled jobs can leave deployed files, cloud resources or external notifications behind. Follow the workflow's own recovery notes;
gh run cancelcannot roll those effects back.
Done means
- Checked the install. The installed
ghversion and authenticated account were confirmed. - Matched the run. The run ID came from a scoped list and matched the intended repository, workflow, branch and commit.
- Inspected right before acting. The run was checked immediately before cancellation.
- Used force sparingly. The normal cancellation command was used, with
--forcereserved for a deliberate escalation. - Verified the outcome. A follow-up query reported
statuscompletedandconclusioncancelled. - Owned the fallout. Any partial deployment or other external side effect has a separate recovery owner and plan.