GitHub Actions workflow not triggering
Fix a GitHub Actions workflow that will not trigger: validate the YAML, check branch and path filters and the default branch. Covers GITHUB_TOKEN and cron.
(no error: the workflow simply does not appear in the Actions tab)
Incident Overview
Fix a GitHub Actions workflow that will not trigger: validate the YAML, check branch and path filters and the default branch. Covers GITHUB_TOKEN and cron.
medium fix·5 min read
By Vishvesh Patel·DevOps Engineer·Updated 21 September 2026
(no error: the workflow simply does not appear in the Actions tab) This workflow has a workflow_dispatch event trigger, but it is not in the default branch. Workflow does not have 'workflow_dispatch' trigger.
Do this first3 steps
Run these in order. Each one tells you what its output means before you change anything.
• Check the file parses at all
An invalid workflow file does not run and does not always surface an error in the Actions tab. Valid YAML is necessary but not sufficient, since the schema also has to be right.
• Confirm the event and branch filters match what happened
Note the quirk: unquoted on is parsed as the boolean True by YAML, which is why this reads both keys. Compare the branches and paths filters against the branch and files you actually pushed.
• Check whether the trigger was another workflow's token
A push made with the default GITHUB_TOKEN deliberately does not trigger further workflow runs, which prevents infinite loops. An author of github-actions[bot] on the triggering commit explains a workflow that never starts.
No error, no run. GitHub evaluated the workflow and decided it did not apply. Work through these.
python3 -c "import yaml,sys; yaml.safe_load(open('.github/workflows/ci.yml')); print('valid YAML')"1. Does the file parse?
An unparseable workflow is skipped. GitHub sometimes surfaces this as an annotation and sometimes not.
Note a YAML quirk that bites here: unquoted on is parsed as the boolean true by YAML 1.1 parsers. GitHub handles it, and your own tooling may not, so d.get('on') returning None in a script does not mean the key is missing.
actionlint catches schema errors that a YAML parse will not:
python3 -c "import yaml; yaml.safe_load(open('.github/workflows/ci.yml')); print('ok')"2. Do the filters match?
Both must match. A push to main touching only README.md does not run this, and that is correct behaviour rather than a fault.
Points worth knowing:
A required status check on a workflow that path-filters itself out never reports, so the pull request blocks forever. Use a skipped-but-reporting job for that:
on:
push:
branches: [main]
paths:
- 'src/**'3. workflow_dispatch and the default branch
The Run workflow button only appears once the workflow file exists on the default branch. Adding workflow_dispatch on a feature branch does nothing visible until it is merged.
Once merged, you can dispatch it against any branch, and the version of the file that runs is the one on the branch you select.
schedule has the same rule: cron triggers only fire from the default branch.
This workflow has a workflow_dispatch event trigger, but it is not in the default branch.
4. A push made by GITHUB_TOKEN
Events created using the default GITHUB_TOKEN deliberately do not trigger further workflow runs. This prevents a workflow that pushes from triggering itself indefinitely.
That explains a workflow that never starts after an automated commit. If you genuinely need the chain, use a PAT or a GitHub App token, and think about the loop you are creating. A workflow_run trigger is often cleaner:
git log -1 --format='%an <%ae>' # github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
5. Scheduled workflows
on:
schedule:
- cron: '0 3 * * *'6. Actions disabled, or a fork
Check Settings → Actions → General. A repository, or an organisation policy above it, can disable Actions entirely or restrict which actions may run.
Forks are their own case: workflows are disabled by default on a fork and must be enabled manually, and a pull_request from a fork runs with a read-only token and no secrets.
The GitLab equivalent
rules and workflow:rules decide whether a pipeline is created at all:
A trailing when: never means anything not matched creates no pipeline, which is intentional and easy to forget.
GitLab also skips pipeline creation when every job is excluded by its own rules, which produces the same silence.
A commit message containing [skip ci] or [ci skip] prevents a pipeline on both platforms, which catches people who use it habitually.
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- when: neverA checklist
Frequently Asked Questions
Why does my workflow_dispatch button not appear?
Because the workflow file must exist on the repository's default branch for GitHub to offer the Run workflow control. Adding workflow_dispatch on a feature branch has no visible effect until it is merged. Once it is on the default branch you can dispatch it against any branch, and the version of the file that executes is the one on the branch you select, not the default branch copy. Scheduled triggers follow the same default-branch rule.
Why did my workflow not run after an automated commit?
Because events created with the default GITHUB_TOKEN do not trigger further workflow runs, which is a deliberate guard against a workflow that pushes triggering itself forever. Check the author of the triggering commit: github-actions[bot] explains it. If you genuinely need the chain, authenticate the push with a personal access token or a GitHub App installation token, or restructure using a workflow_run trigger, which is usually the cleaner option.
How do path filters interact with required status checks?
Badly, if you are not careful. A workflow that filters itself out on a pull request touching no matching paths never reports a status, so a branch protection rule requiring that check blocks the pull request indefinitely. The usual solution is a small gate job that always runs and passes when the real job either succeeded or was skipped, so the required check always reports. Note also that path filters are ignored entirely for workflow_dispatch and schedule.
Why did my scheduled workflow stop running?
Most likely because GitHub disables scheduled workflows after 60 days without repository activity, and it emails the last committer rather than announcing it loudly. Re-enable it in the Actions tab. Two other things worth knowing about schedule: the cron expression is always interpreted as UTC with no timezone option, and runs are queued on a best-effort basis and can be significantly delayed or occasionally skipped under load, so it is unsuitable for anything time-critical.
Why is my GitLab pipeline not created at all?
Usually workflow:rules. A rule set ending in when: never means any commit not matching an earlier condition produces no pipeline, which is intentional but easy to forget when adding a new branch pattern. GitLab also creates no pipeline when every individual job is excluded by its own rules. Validate the file against the project's CI lint API before pushing, and check the commit message for [skip ci], which suppresses pipelines on both platforms.
Reference and practice
Learn the underlying concept
Other CI/CD errors
Free, comprehensive DevOps tutorials and learning roadmaps. Master Docker, Kubernetes, CI/CD, and more.
Get notified about new tutorials and features.
• Roadmaps
• Interview Prep
• Certifications
• Company
© 2026 DevOpsLesson. All rights reserved.
Need to practice this scenario?
Simulate this error condition and practice recovery commands safely in our in-browser terminal.