Start a GitHub Actions workflow from your shell with gh workflow run, without losing track of which ref and inputs you sent. It takes about ten minutes for a first run. You need the GitHub CLI, an authenticated account with permission to dispatch the repository workflow, and a workflow file that declares an on.workflow_dispatch trigger.
The examples were checked with gh version 2.87.3, released on 23 February 2026. The local Debian package record says gh 2.45.0-1ubuntu0.3+esm3, so check the executable you actually invoke if your package and binary versions differ:
$ gh version
gh version 2.87.3 (2026-02-23)
$ command -v gh
/usr/bin/gh
This is an ordinary user command. Do not use sudo: elevated privileges do not grant GitHub repository permission and can select a different configuration or credentials.
Warning: A dispatch is a remote state change. It can start jobs that consume minutes, publish artefacts, change environments or deploy code. There is no general undo for a workflow that has already been queued, so inspect the workflow and its trigger before sending the event.
In the repository checkout, look for the trigger and its declared inputs:
$ rg -n -A12 '^on:|workflow_dispatch' .github/workflows
.github/workflows/triage.yml:3:on:
.github/workflows/triage.yml:4: workflow_dispatch:
.github/workflows/triage.yml:5: inputs:
Use the actual file name and input keys from your repository. A workflow without workflow_dispatch cannot be started by this command, and an input name that is merely similar to the declared one will not do what you intend.
Checkpoint: Write down the repository, workflow file, ref and input values you intend to use. If the workflow can deploy or delete data, stop here until you have checked its approval and environment protections.
Run the read-only status check before building the dispatch command:
$ gh auth status
Logged in to github.com account EXAMPLE_USER
$ gh repo view OWNER/REPO --json nameWithOwner,defaultBranchRef
{"defaultBranchRef":{"name":"main"},"nameWithOwner":"OWNER/REPO"}
The account name and JSON formatting vary. Inside the intended checkout, you can leave OWNER/REPO out of the final command. Otherwise pass --repo OWNER/REPO; it stops you dispatching a similarly named workflow in the wrong repository.
If authentication fails, stop and repair it with your normal GitHub CLI login process. Do not paste a token into a command, shell history or workflow input. Repository access and Actions permission are separate checks: being able to view code does not necessarily allow a dispatch.
The simplest non-interactive form names the workflow file and uses the repository's default branch:
$ gh workflow run triage.yml --repo OWNER/REPO
✓ Created workflow dispatch event for triage.yml at main
The displayed line is representative. The installed command may also return the created run's URL when GitHub makes it available. A successful dispatch is not a successful job: it only means GitHub accepted the event.
Use --ref when the workflow file and the code it should run must come from a specific branch or tag:
$ gh workflow run triage.yml --repo OWNER/REPO --ref release-2026-09
✓ Created workflow dispatch event for triage.yml at release-2026-09
The ref must exist in the repository. It is not a local checkout switch, and it does not make an unpushed local workflow file visible to GitHub. GitHub needs the workflow file at the selected ref, and it must contain the dispatch trigger there.
Checkpoint: If the output names a different repository, workflow or ref from your written plan, stop. Do not immediately rerun with more flags.
For a workflow with inputs such as name and greeting, use one -f or --raw-field option per key:
$ gh workflow run triage.yml \
--repo OWNER/REPO \
--ref main \
--raw-field name='scully' \
--raw-field greeting='hello'
✓ Created workflow dispatch event for triage.yml at main
Quote values that contain spaces, punctuation or shell characters. The option takes key=value, and its short form is -f. The -F or --field form also takes key=value, but follows the GitHub CLI API field convention for an @ value. Use --raw-field when you want a literal string and do not need that convention.
Warning: Do not assume every input is a free-form string. The workflow's YAML defines each input's name, required status, default and type. Treat values that control deployment, deletion or production credentials as security-sensitive, and review the workflow body before dispatching them.
For multiple or structured values, pass JSON on standard input and add --json:
$ printf '%s\n' '{"name":"scully","greeting":"hello"}' \
| gh workflow run triage.yml --repo OWNER/REPO --ref main --json
✓ Created workflow dispatch event for triage.yml at main
This keeps the payload visible before it is sent and avoids an interactive prompt. If another command generates the JSON, validate it locally first:
$ payload='{"name":"scully","greeting":"hello"}'
$ printf '%s\n' "$payload" | jq empty
$ printf '%s\n' "$payload" | gh workflow run triage.yml --repo OWNER/REPO --ref main --json
Tip: Do not put both JSON on standard input and field flags in the same invocation unless you have checked the command's exact input handling. Choose one input method so there is one obvious payload to review.
After dispatching, list recent runs for the workflow and inspect the newest matching entry:
$ gh run list --repo OWNER/REPO --workflow triage.yml --limit 5
STATUS TITLE WORKFLOW BRANCH EVENT ID ELAPSED AGE
queued ... triage main workflow_dispatch 1234567890 ... 3s
Column layout and values vary. The evidence you want is a new run whose event is workflow_dispatch, whose branch or tag is the intended ref, and whose status is progressing or complete. Use its run ID to look closer:
$ gh run view 1234567890 --repo OWNER/REPO
$ gh run watch 1234567890 --repo OWNER/REPO
If the run fails, read its logs and the workflow's conditions before retrying. Sending the same event again does not repair a failed run.
Recovery: If a queued run must be stopped, use the repository's normal Actions cancellation procedure and confirm that any partial external work is safe to leave in place.
workflow_dispatch event is not supported usually means the file is absent at the selected ref, has no dispatch trigger there, or the workflow name was mistyped. Check the file and ref again. A bad input name is fixed by matching the declared key exactly.sudo.gh run list before retrying. That prevents duplicate jobs.on.workflow_dispatch at the selected ref.workflow_dispatch and the expected branch or tag.