Trace and Manage GitHub Actions Runs with gh run
gh run finds a GitHub Actions run, shows you the failing job, and lets you watch, download, rerun, cancel or delete it from one shell. The examples use GitHub CLI 2.87.3, installed on this machine in March 2026. Most commands here take a few minutes; downloading or diagnosing a large run takes as long as the logs and artefacts require.
The route
Jump straight to the step you need, or tick off Done means at the end.
Before you start
Install and authenticate GitHub CLI, then work from a directory where downloaded artefacts can safely live. You need access to the repository and the Actions permissions the operation requires. The commands below use OWNER/REPO as a placeholder: replace it with a real repository such as octo-org/example-app, and replace RUN_ID with the numeric run ID returned by the list command.
gh --version
gh auth status
mkdir -p ~/tmp/gh-run-work
cd ~/tmp/gh-run-work
Checkpoint
Authentication should report the account and host you intend to use. No command in this guide needs sudo; repository permissions are checked by GitHub instead.
1. Find the run
Start with a small list so an old run does not distract you. By default, gh run list fetches at most 20 runs. Filter by workflow, branch, event, status, commit, or triggering user when the repository is busy.
gh run list --repo OWNER/REPO --limit 10
gh run list --repo OWNER/REPO --workflow build.yml --branch main --status failure
The table includes a run status, conclusion, workflow, branch, event, and run ID. A run can be in_progress while its conclusion is not yet final. --workflow takes a workflow name or file, but a disabled workflow needs --all as well when you filter by name.
For scripts, request named JSON fields rather than parsing the display table.
gh run list --repo OWNER/REPO --limit 5 --json databaseId,workflowName,status,conclusion,headBranch,url --jq '.[] | [.databaseId, .workflowName, .status, (.conclusion // "-"), .headBranch, .url] | @tsv'
Checkpoint
Save one numeric databaseId as RUN_ID. If the list is empty, check the repository, branch, workflow filter, and whether your account can see Actions runs at all.
2. Inspect the run and its logs
View a summary first. With no run ID, gh run view selects one interactively, which is handy at a terminal but awkward in automation.
gh run view RUN_ID --repo OWNER/REPO
gh run view RUN_ID --repo OWNER/REPO --verbose
gh run view RUN_ID --repo OWNER/REPO --log-failed
- Use
--logfor the full log. - Use
--log-failedwhen you want the shortest useful diagnostic. - Expect it to be slower sometimes. Logs are fetched as a zip or job by job; the job-by-job fallback is slower and can fail when more than 25 job logs are missing.
For a machine-readable summary, request only the fields you need. If a run has multiple attempts, specify the attempt number.
gh run view RUN_ID --repo OWNER/REPO --json name,number,status,conclusion,jobs,url
gh run view RUN_ID --repo OWNER/REPO --attempt 3
gh run view RUN_ID --repo OWNER/REPO --log --job JOB_ID
The job ID is not necessarily the number shown in a browser URL. Pull the correct database ID from the JSON response instead:
gh run view RUN_ID --repo OWNER/REPO --json jobs --jq '.jobs[] | {name, databaseId}'
Checkpoint
Identify the failed job and the first meaningful error, not just the final summary line. If the failure looks external, rerunning it may produce a different result, so record the evidence first.
3. Watch an active run
When a run is still moving, watch it rather than repeatedly running list. The default refresh interval is three seconds, and compact mode reduces noise by showing only relevant or failed steps.
gh run watch RUN_ID --repo OWNER/REPO
gh run watch RUN_ID --repo OWNER/REPO --compact --interval 10
By default, watch returns successfully when the run finishes, even if the workflow itself failed. Add --exit-status when a shell script must stop on a failed run.
if gh run watch RUN_ID --repo OWNER/REPO --compact --exit-status; then
echo "workflow passed"
else
echo "workflow failed; inspect it with gh run view" >&2
exit 1
fi
Checkpoint
The command has only completed once the run reaches a terminal state. A non-zero exit here is a useful signal, not proof that the CLI itself is broken.
4. Download artefacts into a controlled directory
Without a run ID, gh run download chooses the latest artefact. That is fine for a quick look but unsafe for reproducible troubleshooting, since workflows can delete or overwrite artefacts. Use the run ID whenever the artefact must match the run you inspected.
mkdir -p ./artifacts/RUN_ID
gh run download RUN_ID --repo OWNER/REPO --dir ./artifacts/RUN_ID
gh run download RUN_ID --repo OWNER/REPO --name test-report --dir ./artifacts/RUN_ID
Each artefact is extracted into its own directory unless you select a single one. To see what arrived:
find ./artifacts/RUN_ID -maxdepth 3 -type f -print
Warning
Do not extract untrusted files into a source tree, deployment directory, or home-directory configuration location. The command only changes the destination you provide, so recovery is simply removing that dedicated directory once you have checked its contents.
5. Change a run only after checking the boundary
Rerunning, cancelling, and deleting are state-changing operations. Confirm the repository and run ID immediately before using any of them; rerunning can consume Actions minutes and repeat deployment or release steps.
gh run rerun RUN_ID --repo OWNER/REPO --failed
gh run rerun RUN_ID --repo OWNER/REPO --job JOB_ID
The first command reruns failed jobs and their dependencies. The second targets one job and its dependencies. If you only need more evidence, do not rerun yet.
Cancel a run that should no longer continue. The normal cancellation is preferable; --force is an explicit escalation.
gh run cancel RUN_ID --repo OWNER/REPO
gh run cancel RUN_ID --repo OWNER/REPO --force
Warning
Deletion is irreversible from the CLI. There is no undo command in gh run, and deleting a run removes its run record and available artefacts. Use it only after confirming your retention or audit requirements.
gh run delete RUN_ID --repo OWNER/REPO
Checkpoint
After a rerun, list the repository again and use the new run or attempt details. After a cancellation, view the run to confirm its terminal conclusion. Treat a deletion as final.
Done means
- Selected the right target. You picked the intended repository and recorded a numeric run ID.
- Can read the evidence. You can inspect a summary, failed logs, jobs, and the correct job database ID.
- Can watch and script it. You can watch a run and make failure affect a script's exit status.
- Artefacts land somewhere sane. They are downloaded into a dedicated, known directory.
- Separated looking from changing. You have deliberately kept evidence gathering apart from rerunning, cancelling, or deleting.