Diagnosing GitHub Actions Workflows That Register but Never Run
When a GitHub Actions workflow exists in your repository but no run appears, the failure usually happens at registration, trigger matching, or execution. This guide walks through checks and fixes for each layer.
23 Jan 2026, 20:35 UTC

You push a commit to your repository, open the Actions tab, and no new run appears. Or the workflow file exists in your branch, but GitHub never lists it at all. Because GitHub Actions processes workflow files asynchronously, the repository can appear healthy while a workflow is silently ignored, queued forever, or blocked by a permission error before the first step runs.
The useful takeaway is to split the problem into three layers before changing anything: registration (does GitHub see the file?), triggering (does the event match the filters?), and execution (can the job start and access resources?). This guide walks through checks for each layer, with fixes tied to what you find.
Cause and Diagnostic Table
| Symptom | Probable cause | Quick check |
|---|---|---|
| Workflow missing from Actions tab | Invalid path, tab characters, or unsupported YAML | Open Actions tab; look for a syntax error banner |
| Push completed, no run started | Branch or tag filter in on: does not match the pushed ref | Compare branch name to branches: or branches-ignore: |
| Run starts then fails with 403 | GITHUB_TOKEN lacks write scope for the action | Check Settings > Actions > General > Workflow permissions |
| Job stuck in queued | runs-on refers to an offline or busy self-hosted runner | Check runner status in Settings > Actions > Runners |
| Step references missing output | Previous job or step failed or was skipped | Inspect the failed run's step logs |
Check 1: Confirm the workflow is registered
GitHub only registers workflow files located at .github/workflows/*.yml or .github/workflows/*.yaml in the default branch. Files in nested folders under .github/workflows/ are not picked up, and a file without the .yml or .yaml extension is ignored.
Where to check: GitHub web UI, Actions tab. Required permission: read access to the repository.
- Open your repository on GitHub and click Actions. If the workflow name is absent, registration failed.
- Confirm the file path is exactly
.github/workflows/ci.yml, replacingci.ymlwith your filename. - Open the file and confirm it uses spaces for indentation. GitHub's YAML parser treats a literal tab character as a parse error and may skip the file without a visible run.
- Look for a yellow syntax-error banner at the top of the Actions page. GitHub surfaces line numbers there when the schema is invalid.
Risk: Editing the file directly in the GitHub web editor can introduce smart quotes or trailing whitespace. Validate locally before pushing if possible.
Check 2: Match the event trigger to the ref you pushed
Even a registered workflow will not start if the on: block excludes the branch or tag you pushed.
Example configuration that excludes a common fix branch:
on:
push:
branches:
- main
- 'releases/*'
If you push to fix/login, no run starts because neither main nor releases/* matches that ref.
Diagnostic decision: temporarily broaden the filter to confirm the trigger is the cause:
on:
push:
branches:
- '*'
Commit this change to a throwaway branch, push, and watch the Actions tab. If a run appears, the original filter was too narrow. Restore the specific branches after you confirm, because '*' matches every push and can generate unexpected runs and billed minutes.
For pull_request triggers, remember that the event fires on the pull request's merge ref, not necessarily the head branch you pushed. If your workflow only needs to run on pushes to the head branch, use push rather than pull_request.
Check 3: Inspect job permissions and runner labels
A workflow can start and still fail before the first step if the automatic GITHUB_TOKEN lacks the scope the action needs.
Where to check: Settings > Actions > General > Workflow permissions. Required permission: write access to repository settings to change the default.
Fix: set Workflow permissions to Read and write permissions if your workflow pushes tags, creates releases, comments on pull requests, or writes artifacts to another repository. This applies repository-wide unless overridden per job.
Per-job override example:
jobs:
deploy:
permissions:
contents: write
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Runner check: if the job stays in queued, inspect runs-on. A label such as self-hosted or build-linux only matches runners registered to your repository or organization. If those runners are offline, at capacity, or removed, the job never starts. Switch to ubuntu-latest, windows-latest, or macos-latest for GitHub-hosted runners to test whether the issue is runner availability.
Check 4: Validate conditional outputs and skipped steps
A step that reads ${{ steps.previous-step.outputs.value }} receives an empty string when the previous step failed or was skipped by an if: condition. This is not a syntax error; the workflow continues with missing data.
Debug step to inspect available context without printing secret values:
- name: Inspect context
run: echo '${{ toJson(github) }}'
Where to run: inside any job in your workflow file. Expected check: the step log shows the github object for the current run. Secrets are masked with *** by GitHub's log masking; if a variable you expected is absent, the step that defines it likely did not run.
Fixes tied to findings
- Registration failure: move the file to
.github/workflows/, replace tabs with spaces, and correct YAML indentation. Push to the default branch. - Trigger mismatch: adjust
branches:,tags:, orbranches-ignore:in theon:block to include the ref you are testing. - Permission failure: grant Read and write workflow permissions, or add a
permissions:block to the affected job. - Runner failure: change
runs-onto a GitHub-hosted label or bring the self-hosted runner back online. - Missing output: guard the dependent step with
if: success()or ensure the producing step runs unconditionally.
Escalation criteria
Escalate to GitHub support or your organization's repository administrators when:
- The workflow file passes local validation, appears in the Actions tab, and still produces no runs after you broaden triggers to
'*'. - A self-hosted runner is online and idle but jobs remain queued for more than an hour.
- You receive a 403 error despite setting
contents: writeat both the repository and job level.
Limitations and practical verification
This guide covers public and private repositories using GitHub-hosted or self-hosted runners. It does not cover GitHub Actions for GitHub Enterprise Server, where feature availability depends on your server version.
Practical verification: after applying a fix, push a commit to the affected branch and confirm a run appears in the Actions tab within a few minutes. Open the run and confirm the first job completes instead of staying queued. If you changed workflow permissions, wait up to one minute for the setting to propagate before retesting.
Rollback
Changing on: filters, permissions, or runs-on alters workflow behavior. To roll back, revert the commit that introduced the change and push the previous version of the workflow file.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.